Keeping fit on Java - learning points
- HowtodoinJava
- Spring guides
- DZone java zone
- winterbe
- Journaldev
- Tutorialpoint
- Callicoder.com (CompletableFuture)
- https://dzone.com/articles/20-examples-of-using-javas-completablefuture
- Why Sneaky Throw?
CompletableFuture and Async programming
Multi-threading is similar to multitasking, but enables the processing of executing multiple threads simultaneously, rather than multiple processes. The CompletableFuture, introduced in Java 8, provides an easy way to write asynchronous, non-blocking and multi-threaded code. Spring has the ability to implement the Command Pattern extremely well.
- Java CompletableFuture Tutorial with Examples
- Creating Asynchronous Methods in Springboot
- Guide To CompletableFuture Baeldung
- Spring Boot: Creating Asynchronous Methods Using @Async Annotation
- HowToDoInJava (Spring @Async rest controller example)
- Be aware of ForkJoinPook.CommonPool
SOLID Principles
The SOLID Principles are five principles of Object-Oriented class design. The SOLID principles were first introduced by the famous computer scientist Robert J. Martin (a.k.a Uncle Bob) in his paper in 2000. But the SOLID acronym was introduced later by Michael Feathers.
- The Single Responsibility Principle
- The Open-Closed Principle
- The Liskov Substitution Principle
- The Interface Segregation Principle
- The Dependency Inversion Principle
Gang of Four Design Patterns
As a Java developer using the Spring Framework to develop enterprise class applications, you will encounter the GoF Design Patterns on a daily basis. The GoF Design Patterns are broken into three categories: Creational Patterns for the creation of objects; Structural Patterns to provide relationship between objects; and finally, Behavioral Patterns to help define how objects interact.
- SpringFrameWork Guru about GOF
- Which GoF Design pattern will be changed or influenced by the introduction of lambdas in Java8?
- State Design Pattern in Java
- State of the Lambda, why it will replace parts of GOF behavioral patterns
- Good example of Strategy pattern on How to do in java (EmployeePredicates)
Which design pattern to use on Java workflow
The obvious choice to also consider here is Chain of Responsibility. The problem with CoR in cases like this is sometimes you don't really know what the paths will be in advance, and so laying out all the possible paths can be really painstaking. Of course, you could use a builder to construct the chains (remember all the Maze building examples from the Gang of Four).
Command Pattern and Springboot
Command Pattern is one of the design patterns and encapsulates everything required to take any action and allows loosely coupled execution of the action. How does that relate to invoking REST API with Spring boot Java?
It is always a good practice to develop around established patterns.
- Command Pattern for Invoking REST API with Spring boot Java
- Leveraging command pattern with Spring
- Command Patterns in Spring Framework DZone
- Morning Joe: Using the command pattern in Spring
Building your own Fluent API Pattern
Writing Kubernetes Operators in Java
Java is no doubt one of the most popular programming languages in the world but it's been difficult for a period time for those non-Golang developers to build up their customized controller/operator due to the lack of library resources in the community. In the world of Golang, there're already some excellent controller frameworks. Driven by the emerging need of further integration into the platform of Kubernetes, we not only ported many essential toolings from the Golang SDK into the kubernetes Java SDK including informers, work-queues, leader-elections, etc. but also developed a controller-builder SDK which wires up everything into a runnable controller without hiccups.
- About k8s operators
- Develop a Kubernetes controller in Java at kubernetes.io
- Your own Kubernetes controller - Developing in Java
- Another good post
- Kubernetes Java Client at Github
First setup
- kubectl cluster-info
- kubectl get nodes
- kubectl config set-context (kubectl config current-context) --namespace=default
- kubectl config view | grep namespace:
Resources
- kubectl get nodes
- kubectl get po
- kubectl get pods --all-namespaces
- kubectl get pods -n default
- kubectl get namespaces
- kubectl get svc
- kubectl get pods -o wide
- kubectl get -f pod.yaml -o json
- kubectl get rc,services
Deployments
- kubectl run first-deployment --image=katacoda/docker-http-server --port=80 --replicas=1
- kubectl expose deployment first-deployment --port=80 --type=NodePort
- export PORT=$(kubectl get svc first-deployment -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}')
- kubectl apply -f /opt/kubernetes-dashboard.yaml
- kubectl get deployments
- kubectl run httpexposed --image=katacoda/docker-http-server:latest --replicas=1 --port=80 --hostport=8001
- kubectl scale --replicas=3 deployment http
- kubectl create -f deployment.yaml
- kubectl get deployment
3 Patterns combined
- Strategy design pattern at Baeldung
- Fluent Builder pattern at DZone
- Strategy pattern at Howtodoinjava
@Data
@NoArgsConstructor
@ToString
public class Case implements Strategy {
private String phase;
private String status;
private Instant dueDate = Instant.now();
}
public interface Strategy {
default Case thenApply(Consumer<Case> logic) {
logic.accept((Case)this);
return (Case)this;
}
public static Consumer<Case> kycReview() {
return c -> c.setPhase(CasePhase.KYC_REVIEW.name());
}
public static Consumer<Case> priReview() {
return c -> c.setPhase(CasePhase.PRI_REVIEW.name());
}
public static Consumer<Case> rejected() {
return c -> c.setStatus(CaseStatus.REJECTED.name());
}
public static Consumer<Case> verify(Boolean check) {
return c -> {
if (check && c.getDueDate().isBefore(Instant.now())) {
c.setStatus(CaseStatus.DECLINED.name());
}
};
}
}
// finally
Case myCase = new Case();
myCase.thenApply(rejected()).thenApply(kycReview()).thenApply(priReview()).thenApply(verify(true)).compute();
System.out.println(myCase);