2022-12-23
Spring Cloud, Spring Boot, Rabbitmq In Kotlin

what is spring cloud

Spring Cloud is a set of tools for building microservices-based applications that use Spring Framework, a popular Java-based application development framework. It provides a number of features that can help you build distributed systems that are resilient, reliable, and scalable.

Spring Cloud provides a number of tools for building microservices, including:

Service discovery: Spring Cloud provides a service registry and a load balancer for discovering and routing to service instances.

Circuit breaker: Spring Cloud provides a circuit breaker pattern implementation that can help prevent cascading failures in distributed systems.

Configuration management: Spring Cloud provides a centralized configuration server for storing and managing application configuration data.

API gateway: Spring Cloud provides an API gateway that can route requests to the appropriate service, perform authentication and authorization, and provide other security features.

Distributed tracing: Spring Cloud provides support for distributed tracing, which can help you understand the flow of requests through your system and identify performance issues.

Spring Cloud is built on top of Spring Boot, which makes it easy to get started with microservices development using the Spring Framework. It is also fully integrated with the rest of the Spring ecosystem, including Spring Data, Spring Security, and Spring Cloud Stream.

use spring cloud in kotlin

Spring Cloud can be used with Kotlin, a statically-typed programming language that is fully interoperable with Java and runs on the Java Virtual Machine (JVM). To use Spring Cloud with Kotlin, you can follow these steps:

Set up a Kotlin project: You can use a build tool like Gradle or Maven to set up a Kotlin project. Make sure to include the necessary dependencies for Spring Cloud, such as the spring-cloud-starter-netflix-eureka-client for service discovery or the spring-cloud-starter-netflix-ribbon for load balancing.

Configure your application: You can use the @SpringBootApplication annotation to enable auto-configuration and component scanning in your Kotlin application. You can also use the application.properties file or the application.yml file to configure your application’s properties.

Create a Spring Boot application class: You can create a Kotlin class with the @SpringBootApplication annotation and the main function to bootstrap your application. This class will serve as the entry point to your application.

Define your microservices: You can define your microservices as Kotlin classes annotated with @RestController and @RequestMapping. These classes will handle incoming HTTP requests and return responses to the client.

Use Spring Cloud features: You can use the various features of Spring Cloud, such as service discovery, circuit breaking, configuration management, and distributed tracing, in your Kotlin application by using the appropriate annotations and components provided by Spring Cloud.

Here is an example of a simple Kotlin application using Spring Cloud:

1
2
3
4
5
6
7
8
9
10
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
class MyApplication
fun main(args: Array<String>) {
SpringApplication.run(MyApplication::class.java, *args)
}

This application uses the @EnableDiscoveryClient annotation to enable service discovery using Spring Cloud Netflix Eureka. You can then use other Spring Cloud features, such as circuit breaking or configuration management, by including the necessary dependencies and using the appropriate annotations and components.

write spring eureka client in kotlin to connect to eureka server

Here is an example of how you can write a Spring Cloud Eureka client in Kotlin to connect to a Eureka server:

1
2
3
4
5
6
7
8
9
10
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
class EurekaClientApplication
fun main(args: Array<String>) {
SpringApplication.run(EurekaClientApplication::class.java, *args)
}

This application uses the @EnableDiscoveryClient annotation to enable service discovery using Spring Cloud Netflix Eureka. The @SpringBootApplication annotation enables auto-configuration and component scanning in the application.

To connect to the Eureka server, you will need to provide the URL of the Eureka server in the application.properties or application.yml file. For example:

1
2
3
4
5
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

You can then use the @Value annotation to inject the Eureka server URL into your Kotlin code:

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.beans.factory.annotation.Value
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class EurekaClientController {
@Value("\${eureka.client.serviceUrl.defaultZone}")
lateinit var eurekaServerUrl: String
@GetMapping("/eureka-server-url")
fun getEurekaServerUrl(): String {
return eurekaServerUrl
}
}

This controller has a getEurekaServerUrl method that returns the URL of the Eureka server. You can then make a GET request to /eureka-server-url to get the Eureka server URL.

You can also use the DiscoveryClient interface provided by Spring Cloud to interact with the Eureka server and perform operations such as registering a service or discovering service instances.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cloud.client.discovery.DiscoveryClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class EurekaClientController {
@Autowired
lateinit var discoveryClient: DiscoveryClient
@GetMapping("/service-instances")
fun getServiceInstances(): List<String> {
return discoveryClient.services
}
}

This controller has a getServiceInstances method that returns a list of all the service instances registered with the Eureka server. You can then make a GET request to /service-instances to get the list of service instances.

run eureka server kotlin

To run a Eureka server in Kotlin, you can follow these steps:

Set up a Kotlin project: You can use a build tool like Gradle or Maven to set up a Kotlin project. Make sure to include the necessary dependencies for Spring Cloud Eureka Server, such as the spring-cloud-starter-netflix-eureka-server dependency.

Configure your application: You can use the application.properties file or the application.yml file to configure your Eureka server. For example, you can set the server.port property to specify the port on which the Eureka server will run, and the eureka.client.register-with-eureka and eureka.client.fetch-registry properties to enable or disable the registration and fetching of registry information for the Eureka server.

Create a Spring Boot application class: You can create a Kotlin class with the @SpringBootApplication annotation and the main function to bootstrap your application. This class will serve as the entry point to your Eureka server.

Enable Eureka server: You can use the @EnableEurekaServer annotation to enable the Eureka server in your application.

Here is an example of a simple Kotlin application that runs a Eureka server:

1
2
3
4
5
6
7
8
9
10
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
class EurekaServerApplication
fun main(args: Array<String>) {
SpringApplication.run(EurekaServerApplication::class.java, *args)
}

This application uses the @EnableEurekaServer annotation to enable the Eureka server and the @SpringBootApplication annotation to enable auto-configuration and component scanning.

To start the Eureka server, you can run the main function of the EurekaServerApplication class. The Eureka server will start up on the port specified in the application.properties or application.yml file (by default, it will run on port 8761). You can then access the Eureka server dashboard at http://localhost:8761.

spring cloud alternative in kotlin

There are a number of alternatives to Spring Cloud that you can use in Kotlin to build distributed systems and microservices-based applications. Some options include:

Micronaut: Micronaut is a modern, lightweight, and fast microservices framework for the JVM. It provides features such as service discovery, configuration management, and distributed tracing, and is fully compatible with Kotlin.

Quarkus: Quarkus is a Kubernetes-native Java framework that is optimized for low memory footprint and fast startup time. It provides a number of features for building microservices, including service discovery, configuration management, and security. Quarkus is fully compatible with Kotlin and can be used to build cloud-native applications.

Vert.x: Vert.x is a reactive, non-blocking, event-driven Java framework that is designed for building distributed systems and microservices. It provides features such as service discovery, load balancing, and distributed tracing, and is fully compatible with Kotlin.

Helidon: Helidon is a lightweight, cloud-native Java framework that is designed for building microservices and reactive applications. It provides features such as service discovery, configuration management, and security, and is fully compatible with Kotlin.

Eclipse MicroProfile: Eclipse MicroProfile is an open-source specification for building microservices-based applications. It provides a number of features for building distributed systems, including service discovery, configuration management, and security, and is fully compatible with Kotlin.

You can choose the appropriate microservices framework based on your requirements and preferences. All of these frameworks provide support for building microservices in Kotlin and offer a number of features that can help you build distributed systems that are resilient, reliable, and scalable.

which one requires least code

It is difficult to say which microservices framework requires the least amount of code, as it depends on the specific requirements of your application and the features you need to implement. Some frameworks, such as Micronaut and Quarkus, are designed to be lightweight and fast, and may require less code to implement certain features compared to other frameworks. However, this may come at the cost of flexibility or a larger learning curve.

It is important to evaluate the different microservices frameworks based on your specific requirements and choose the one that best fits your needs. You should consider factors such as the performance and scalability requirements of your application, the features and capabilities of the framework, and the level of support and documentation available.

It is also worth noting that writing less code does not necessarily mean that your application will be easier to maintain or more efficient. In some cases, using a more feature-rich framework that requires more code may result in a more maintainable and scalable application in the long run.

recommend compatible package builder/manager for kotlin but simpler than maven

If you are looking for a package builder and manager for Kotlin that is simpler than Maven, you may want to consider Gradle. Gradle is an open-source build automation tool that is designed to be flexible, efficient, and easy to use. It is fully compatible with Kotlin and can be used to build, test, and publish Kotlin applications.

Some of the benefits of using Gradle for Kotlin projects include:

Concise and expressive build scripts: Gradle build scripts are written in a domain-specific language (DSL) that is designed to be concise and expressive. This makes it easier to understand and maintain build scripts, compared to Maven’s XML-based syntax.

Support for multiple languages: Gradle supports building projects in multiple languages, including Kotlin, Java, and C/C++. This makes it a good choice for multi-language projects.

Rich plugin ecosystem: Gradle has a rich plugin ecosystem that provides a wide range of functionality, including support for testing, code analysis, and publishing. This makes it easy to extend and customize your build process.

Fast and incremental builds: Gradle uses a caching mechanism and an incremental build approach to make builds faster and more efficient. This can be especially useful for larger projects.

To get started with Gradle for Kotlin, you can create a new Kotlin project using the kotlin-gradle-plugin, and define your dependencies in the build.gradle file. You can then use the gradle command-line tool or the Gradle wrapper to build, test, and publish your Kotlin application.

Here is an example of a simple build.gradle file for a Kotlin project using Gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.21'
}
group = 'com.example'
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
}
tasks.withType<Test> {
useJUnitPlatform()
}

This build.gradle file defines the kotlin-jvm plugin, the group and version of the project, the dependencies of the project, and the test task. You can then use the gradle command-line tool or the Gradle wrapper to build, test, and publish your Kotlin application.

use rabbitmq client in kotlin

To use RabbitMQ, a message broker that supports a number of messaging protocols, in Kotlin, you can use the amqp-client library, which is a Java client library for RabbitMQ.

To get started with the amqp-client library in Kotlin, you can include the amqp-client dependency in your project. For example, if you are using Maven, you can add the following dependency to your pom.xml file:

1
2
3
4
5
6
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.11.0</version>
</dependency>

If you are using Gradle, you can add the following dependency to your build.gradle file:

1
2
3
4
dependencies {
implementation 'com.rabbitmq:amqp-client:5.11.0'
}

Once you have included the amqp-client dependency in your project, you can use the classes and interfaces provided by the library to connect to a RabbitMQ server and perform operations such as sending and receiving messages.

Here is an example of how you can use the amqp-client library in Kotlin to send a message to a RabbitMQ server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.rabbitmq.client.ConnectionFactory
import com.rabbitmq.client.Connection
import com.rabbitmq.client.Channel
fun main() {
val factory = ConnectionFactory()
factory.host = "localhost"
val connection: Connection = factory.newConnection()
val channel: Channel = connection.createChannel()
val exchangeName = "my_exchange"
val routingKey = "my_routing_key"
val message = "Hello, RabbitMQ!"
channel.basicPublish(exchangeName, routingKey, null, message.toByteArray())
println(" [x] Sent '$message'")
channel.close()
connection.close()
}

This example connects to a RabbitMQ server running on localhost, creates a channel, and uses the basicPublish method to send a message to the server with a specified exchange name and routing key.

You can also use the amqp-client library in Kotlin to receive messages from a RabbitMQ server. Here is an example of how you can use the amqp-client library in Kotlin to receive messages from a RabbitMQ server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import com.rabbitmq.client.ConnectionFactory
import com.rabbitmq.client.Connection
import com.rabbitmq.client.Channel
import com.rabbitmq.client.DeliverCallback
fun main() {
val factory = ConnectionFactory()
factory.host = "localhost"
val connection: Connection = factory.newConnection()
val channel: Channel = connection.createChannel()
val queueName = "my_queue"
channel.queueDeclare(queueName, false, false, false, null)
val deliverCallback = DeliverCallback { _, delivery ->
val message = String(delivery.body, Charsets.UTF_8)
println(" [x] Received '$message'")
}
channel.basicConsume(queueName, true, deliverCallback, _ -> {})
}

This code creates a queue and sets up a DeliverCallback to handle incoming messages. The basicConsume method is used to start consuming messages from the queue. When a message is received, the DeliverCallback is invoked and the message is printed to the console.

You can find more information about using the amqp-client library in Kotlin to interact with a RabbitMQ server in the RabbitMQ documentation and the amqp-client library documentation.

set the delivery mode to persistent

To set the delivery mode of a message to persistent when using the amqp-client library in Kotlin, you can use the basicPublish method and set the deliveryMode property of the BasicProperties object that you pass as the third argument.

Here is an example of how you can set the delivery mode of a message to persistent when using the amqp-client library in Kotlin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.rabbitmq.client.ConnectionFactory
import com.rabbitmq.client.Connection
import com.rabbitmq.client.Channel
import com.rabbitmq.client.BasicProperties
fun main() {
val factory = ConnectionFactory()
factory.host = "localhost"
val connection: Connection = factory.newConnection()
val channel: Channel = connection.createChannel()
val exchangeName = "my_exchange"
val routingKey = "my_routing_key"
val message = "Hello, RabbitMQ!"
val properties = BasicProperties.builder()
.deliveryMode(2)
.build()
channel.basicPublish(exchangeName, routingKey, properties, message.toByteArray())
println(" [x] Sent '$message'")
channel.close()
connection.close()
}

In this example, the BasicProperties.builder method is used to create a BasicProperties object with the deliveryMode property set to 2 (indicating persistent delivery). This object is then passed as the third argument to the basicPublish method.

You can find more information about the BasicProperties class and the different delivery modes in the amqp-client library documentation.

write spring boot hello world with kotlin

To write a “Hello, World!” program in Spring Boot using Kotlin, you can follow these steps:

Create a new Spring Boot project using the Spring Initializr. You can do this by visiting https://start.spring.io/ and selecting “Kotlin” as the programming language. Select the “Web” dependency, and then click on “Generate” to download the project as a ZIP file.

Extract the ZIP file and open the project in your preferred development environment.

In the src/main/kotlin directory, create a new Kotlin file called HelloController.kt. This file will contain a simple controller that will handle HTTP requests to the root path of the application.

In HelloController.kt, define a controller class and annotate it with @RestController. This will enable the class to handle HTTP requests and return responses to the client.

1
2
3
4
5
import org.springframework.web.bind.annotation.RestController
@RestController
class HelloController {
}

Inside the HelloController class, define a method that will handle HTTP GET requests to the root path of the application. Annotate this method with @GetMapping(“/“).

1
2
3
4
5
6
7
8
9
import org.springframework.web.bind.annotation.GetMapping
@RestController
class HelloController {
@GetMapping("/")
fun sayHello(): String {
return "Hello, World!"
}
}

Run the Spring Boot application by running the main method in the Application class. You should now be able to visit http://localhost:8080/ in your web browser and see the message “Hello, World!” displayed.

That’s it! You have now written a simple “Hello, World!” program in Spring Boot using Kotlin.

Read More

2022-12-15
Useful Java Patterns

java stream guide

learn java and kotlin the same time?

beanshell syntax highlight seems to be rare. beanshell workspace has the highlight.

use v2.1.1 and above for varargs support.

there are eclipse and jetbrains plugin support for beanshell.

creating lists

1
2
3
4
5
6
7
8
var a = new ArrayList<>(Arrays.asList(1,2,3));
var mset = new HashSet<>();
mset.addAll(a);
var mset2 = a.stream().collect(Collectors.toSet());
var mymin = Collections.min(a);
var mymax = Collections.max(a);
Collections.reverse(a);

1
2
3
4
5
6
var a = arrayOf(1,2,3);
print(a.contentToString())
print(a.max())
print(a.min())
a.reverse()

creating hashmap

1
2
3
var ah= new HashMap<>();
ah.put(1,2);

1
2
var ah = hashMapOf(1 to 2, 2 to 3)

iterate lists with indices

java double colon :: operator acts as anonymous function

1
2
3
4
5
6
7
8
9
10
11
12
var l = a.listIterator();
while (l.hasNext()){
var index = l.nextIndex();
var val = l.next();
System.out.println("INDEX: "+index+" ELEM: "+val);
}
IntStream.range(0,a.size()).forEach(index -> a.get(index));
var index=0;
for (int i: a){
index++;
}

1
2
3
4
5
6
7
8
9
a.forEachIndexed{ind, elem -> println("index? $ind"); println("elem? $elem")}
for (var i in a.indices){
var elem = a[i]
}
a.indices.forEach {
var elem = a[it]
elem
}

list comprehension

1
2
3
4
var mlist = a.stream().map(x-> x*2).collect(Collectors.toList());
var evenNums = a.stream().filter(x-> x%2 == 0).collect(Collectors.toList());
var mmap = a.stream().collect(Collectors.toMap(x->x.getId(),x->x.getName()));

switch expressions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var val = 2;
var mswitch = switch (val){
case 1,2,3 -> {
yield "good";
}
case 4,5,6 -> {
yield "bad";
} // either throw or yield.
default -> {
System.out.println("out of expectation");
yield "really bad";
}
};
System.out.println(mswitch);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var grade = 30
var res = when(grade) {
in 0..40 -> "Fail"
in 41..70 -> "Pass"
in 71..100 -> "Distinction"
else -> false
}
print(res)
var mcase = 1
var res = when(mcase){
1 -> "good"
2 -> "bad"
else -> "really bad"
}
print(res)

count occurance of elements in array

1
2
3
4
5
6
7
8
9
10
11
12
String[] array = {"name1","name2","name3","name4", "name5", "name2"};
Arrays.stream(array)
.collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k+" "+v.size()));
List asList = Arrays.asList(array);
Set<String> mySet = new HashSet<String>(asList);
for(String s: mySet){
System.out.println(s + " " + Collections.frequency(asList,s));
}
Map<String, Long> map = Arrays.stream(array)
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));

1
2
3
var a = arrayOf(1,2,3,3,3,3)
a.toSet().forEach{it -> println("elem? $it"); println("count? "+a.count{it2->it2 == it})}

lambdas

1
2
3
4
5
6
Consumer mcons = (n) -> {System.out.println(n);}
mcons.andThen(mcons).accept("mval");
Function <Integer,Integer> mfunc = n-> n+1;
Supplier msup = () -> 1;
var mval = msup.get();

1
2
3
var mfunc = {n :Int -> n+1}
var mprint = {n:Any -> print(n)}

Read More

2022-12-13
Rare Package Managers, Alternative Jvm Languages And Java Study Hints

package managers

c, c++

conan

clibs

vcpkg

lisp

CLPM powered by quicklisp

jvm alternative languages

oracle’s blog on jvm languages showing advantages

RingoJS

Kotlin

Scala

Groovy

Clojure

Fantom

Ceylon

Jython

JRuby

Frege haskell on jvm

Xtend

Golo

Concurnaas

Yeti

GraalVM uses polyglot to bridge with other languages

java hints

javac doc

jshell

nashorn js engine run it with jjs

Read More