There are different ways to create data services. The choice for a specific technology to use, depends on several factors inside the organisation which wishes to realize these services. In this blog post I'll provide a minimal sample on how you can use Spring Boot with Apache Camel to call an Oracle database procedure which returns the result of an SQL query as an XML. You can browse the code here.
Articles containing tips, tricks and nice to knows related to IT stuff I find interesting. Also serves as online memory.
Friday, September 27, 2019
Tuesday, September 3, 2019
Microservice framework startup time on different JVMs
When developing microservices, a fast startup time is useful. It can for example reduce the amount of time a rolling upgrade of instances takes and reduce build time thus shortening development cycles. When running your code using a 'serverless' framework such as for example Knative or FnProject, scaling and getting the first instance ready is faster.
When you want to reduce startup time, an obvious thing to look at is ahead of time (AOT) compilation such as provided as an early adopter plugin as part of GraalVM. Several frameworks already support this out of the box such as Helidon SE, Quarkus and Micronaut. Spring will probably follow with version 5.3 Q2 2020. AOT code, although it is fast to startup, still shows differences per framework. Which framework produces the native executable which is fastest to start?
If you need specific libraries which cannot be natively compiled (not even when using the Tracing Agent), using Java the old-fashioned JIT way is also an option. You will not achieve start-up times near AOT start-up times but by choosing the right framework and JVM, it can still be acceptable.
If you need specific libraries which cannot be natively compiled (not even when using the Tracing Agent), using Java the old-fashioned JIT way is also an option. You will not achieve start-up times near AOT start-up times but by choosing the right framework and JVM, it can still be acceptable.
In this blog post I'll provide some measures which I did on start-up times of minimal implementations of several frameworks and an implementation with only Java SE. I've looked at both JIT and AOT (wherever this was possible) and ran the code on different JVMs.
Labels:
aot,
file size,
graalvm,
helidon,
jit,
performance,
quarkus,
servlet engine,
spring,
startup
Friday, August 9, 2019
Apache Camel and Spring Boot: Calling multiple services in parallel and merging results
Sometimes you have multiple services you want to call at the same time and merge their results when they're all in (or after a timeout). In Enterprise Integration Patterns (EIP) this is a Splitter followed by an Aggregator. I wanted to try and implement this in Spring Boot using Apache Camel so I did. Since this is my first quick try at Apache Camel, I might not have followed much best practices. I used sample code from Baeldungs blog, combined it with this sample of sending parallel requests using Futures. You can browse my code here.
Labels:
aggregator,
camel,
eap,
java,
splitjoin,
splitter,
spring boot
Friday, July 26, 2019
A transparent Spring Boot REST service to expose Oracle Database logic
Sometimes you have an Oracle database which contains a lot of logic and you want to expose specific logic as REST services. There are a variety of ways to do this. The most obvious one to consider might be Oracle REST Data Services. It is quite powerful and supports multiple authentication mechanisms like OAuth. Another option might be using the database embedded PL/SQL gateway This gateway however is deprecated for APEX and difficult to tune (believe me, I know).
Sometimes there are specific requirements which make the above solutions not viable. For example if you have complex custom authentication logic implemented elsewhere which might be difficult to translate to ORDS or the embedded PL/SQL gateway. ORDS also runs in stand-alone in a Docker container but this is not so easy for the PL/SQL gateway. Also if you are looking for a product or framework which can be used for multiple flavors of database, these solutions might be too Oracle specific.
You can consider creating your own custom service in for example Java. The problem here however is that it is often tightly coupled with the implementation. If for example parameters of a database procedure are mapped to Java objects or a translation from a view to JSON takes place in the service, there is often a tight coupling between the database code and the service.
In this blog post I'll provide a solution for a transparent Spring Boot REST service which forwards everything it receives to the database for further processing without this tight coupling, only to to a generic database procedure to handle all REST requests. The general flow of the solution is as follows:
Sometimes there are specific requirements which make the above solutions not viable. For example if you have complex custom authentication logic implemented elsewhere which might be difficult to translate to ORDS or the embedded PL/SQL gateway. ORDS also runs in stand-alone in a Docker container but this is not so easy for the PL/SQL gateway. Also if you are looking for a product or framework which can be used for multiple flavors of database, these solutions might be too Oracle specific.
You can consider creating your own custom service in for example Java. The problem here however is that it is often tightly coupled with the implementation. If for example parameters of a database procedure are mapped to Java objects or a translation from a view to JSON takes place in the service, there is often a tight coupling between the database code and the service.
In this blog post I'll provide a solution for a transparent Spring Boot REST service which forwards everything it receives to the database for further processing without this tight coupling, only to to a generic database procedure to handle all REST requests. The general flow of the solution is as follows:
- The service receives an HTTP request from a client
- Service translates the HTTP request to an Oracle database REST_REQUEST_TYPE object type
- Service calls the Oracle database over JDBC with this Object
- The database processes the REST_REQUEST_TYPE and creates a REST_RESPONSE_TYPE Object
- The database returns the REST_RESPONSE_TYPE Object to the service
- The service translates the REST_RESPONSE_TYPE Object to an HTTP response
- The HTTP response is returned to the client
Labels:
hikari,
http,
jdbc,
object,
oracle database,
ords,
rest,
spring boot,
transparent
Thursday, June 6, 2019
Graceful shutdown of forked workers in Python and JavaScript running in Docker containers
You might encounter a situation where you want to fork a script during execution. For example if the amount of forks is dependent on user input or another specific situation. I encountered such a situation in which I wanted to put load on a service using multiple concurrent processes. In addition, when running in a docker container, only the process with PID=1 receives a SIGTERM signal. If it has terminated, the worker processes receive a SIGKILL signal and are not allowed a graceful shutdown. In order to do a graceful shutdown of the worker processes, the main process needs to manage them and only exit after the worker processes have terminated gracefully. Why do you want processes to be terminated gracefully? In my case because I store performance data in memory (disk is too slow) and only write the data to disk when the test has completed.
This seems relatively straightforward, but there are some challenges. Also I implemented this in JavaScript running on Node and in Python. Python and JavaScript handle forking differently.
This seems relatively straightforward, but there are some challenges. Also I implemented this in JavaScript running on Node and in Python. Python and JavaScript handle forking differently.
Labels:
docker,
entrypoint,
fork,
forking,
graceful shutdown,
javascript,
node,
node.js,
process,
python,
sigint,
sigterm
Saturday, June 1, 2019
Performance! 3 reasons to stick to Java 8 for the moment
It is a smart thing to move to newer versions of Java! Support such as security updates and new features are just two of them but there are many more. Performance might be a reason to stick to Java 8 though. In this blog post I'll show some results of performance tests I have conducted showing Java 11 has slower startup times and slightly slower throughput compared to Java 8 when using the same Java code. Native images (a GraalVM feature) have greatly reduced startup time and memory usage at the cost of throughput. You can only compile Java 8 byte-code to a native image though (at the moment).
Saturday, March 23, 2019
6 tips to make your life with Vagrant even better!
HashiCorp Vagrant is a great tool to quickly get up and running with a development environment. In this blog post I'll give some tips to make your life with Vagrant even better! You can find an example which uses these tips here.
Subscribe to:
Posts (Atom)