Software Engineering
Microservices, Big Data, IoT, NLP, AI all welcome in one place
Wednesday, November 22, 2023
Let's try to build scrum masters/project managers/software architects/even a company with training AI models
Saturday, November 11, 2023
Chat with PDF, TXT, and CSV privately (PrivateGPT) suitable for more data sensitive organisations (To be reviewed)
The newly introduced PrivateGPT is a production ready and most suitable for the organisations who handles extremely sensitive data as per their documentation. To be carefully considered. To find out more information.
https://github.com/imartinez/privateGPT/tree/main
Saturday, October 21, 2023
Problem Solving: Allotment calculator
Problem Statement:
Suppose the Government plans to issue up to $10,000 of Savings Bonds. Four individuals applied for a total of $18,000 of Savings Bonds: A ($2,000), B ($4,000) C ($5,500) and D ($6,500).
The available bonds will be spread out among as many investors as possible in the following manner:
- Applications are filled in denominations of $500 upwards.
- After Round 4, $8,000 of Savings Bonds have been allotted, and Investor A's application has been fully met. $2,000 of Savings Bonds are left.
- In Round 5, $1,500 of Savings Bonds are allotted.
- In Round 6, the remaining $500 is insufficient to fill all applications.
- One person among Investor B, Investor C and Investor D is randomly allotted the remaining $500. In this case, Investor C gets it.
The cutoff amount in this case is $2,500. In the final allotment:
- Investor A is allotted $2,000.
- Investor B and Investor D get $2,500 each.
- Investor C gets $3,000.
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
public class SbPlanningCalculator {
private final static Integer MIN = 500;
private final static Integer MAX = 2_00_000;
private final static Predicate<List<User>> isAllValid = users -> {
int allCount = users.size();
int validCount = (int)users.stream().
map(User::getValue).
filter(value -> value >= MIN && value <= MAX && value % MIN == 0).
count();
return allCount == validCount;
};
public static Map<String, Integer> calculateMyPotential(List<User> users, Integer issuedAmount){
if(!isAllValid.test(users)){
System.err.print("Found Invalid Amounts among the users. ");
return null;
}
int total = 0;
Map<String, Integer> allotments = new HashMap<>(0);
int rounds = Math.divideExact(issuedAmount, users.size() * MIN);
int i = 0;
while(i <= rounds) {
for (User user : users) {
int issuedBalanceTotal = issuedAmount - total;
if (issuedBalanceTotal == 0) {
break;
}
if (user.getValue() >= MIN) {
total = total + MIN;
user.setValue(user.getValue() - MIN);
if (allotments.containsKey(user.getName())) {
int userAllotment = allotments.get(user.getName());
allotments.put(user.getName(), userAllotment + MIN);
} else {
allotments.put(user.getName(), MIN);
}
}
}
i++;
}
return allotments;
}
}
Test Cases:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class SbPlanningCalculatorTest {
@Test
void testCalculateMyPotentialCase1(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2000));
users.add(new User("B", 4000));
users.add(new User("C", 5500));
users.add(new User("D", 6500));
Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 10000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(10000, sum);
}
@Test
void testCalculateMyPotentialCase2(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2000));
users.add(new User("B", 4000));
users.add(new User("C", 5500));
users.add(new User("D", 26000));
Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(37500, sum);
}
@Test
void testCalculateMyPotentialCase3(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 500));
users.add(new User("B", 2_00_000));
users.add(new User("C", 14000));
users.add(new User("D", 26000));
Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(2_40_500, sum);
}
@Test
void testCalculateMyPotentialCase4(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 1_000_000));
users.add(new User("B", 2_00_000));
users.add(new User("C", 250));
users.add(new User("D", 26000));
Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
System.out.println(allotments);
Assertions.assertNull(allotments);
}
@Test
void testCalculateMyPotentialCase5(){
List<User> users = new ArrayList<>(0);
users.add(new User("A", 2_00_000));
users.add(new User("B", 2_00_000));
users.add(new User("C", 2_00_000));
users.add(new User("D", 26000));
for(int x = 0; x < 5500; x++){
users.add(new User("X" + x, 2_00_000));
}
Map<String, Integer> allotments = SbPlanningCalculator.calculateMyPotential(users, 1_000_000_000);
assert allotments != null;
var x = allotments.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.counting()));
System.out.println(x);
long sum = x.entrySet().stream().map(e -> e.getKey() * e.getValue()).mapToLong(l -> l).sum();
Assertions.assertEquals(1_000_000_000, sum);
}
}
Monday, January 9, 2023
Supersonic, Subatomic Cloud Native gRPC endpoint implementation with Quarkus
Quarkus gRPC Service Implementation from the scratch
Requirement
In order to produce most reliable, fast and maintainable products we can use Quarkus (
Supersonic, Subatomic Cloud Native Java Framework) as a foundational technology for our backend
services.
Our task it to use [Quarkus](https://quarkus.io/) and [gRPC](https://grpc.io/) to build a
microservice running in [Kubernetes](https://kubernetes.io/) with the following capabilities:
1. The microservice should expose APIs for Smart Models and Smart Features
2. Smart Model is a generic model which can be used to describe your favourite Services and IoT
Devices. Think about the following examples for:
- Devices: Smart Watch, Remotely Controllable Camera, etc
- Services: Open Weather Map, IMDB Movie Database, etc
3. Smart Feature is a specific feature of this smart model which describes one functionality. we can
consider following examples for:
- Devices: Take Camera Screenshot, Get Camera Live Video URL, Get Calories burned for a day
- Services: Get Weekly Forecast in a City, Get Daily Forecast for a State, Search Movie
4. One Smart Model contains several smart features.
5. The microservice should allow storing the smart features and services in a persistent storage and
retrieving them based on information as name, identifier, type and category.
6. Generate data for a few example Smart Services and Smart Features by our self for demonstration
purposes.
Hints
Fully implemented project
Sunday, October 31, 2021
Climate Change News from all over the world through API
Free Public API - Climate Change News
Friday, July 16, 2021
Microsoft Azure + Spring Cloud Sample application from the scratch
Objectives
In this post, we will:
- Set up an Azure Spring Cloud cluster
- Configure a Spring Cloud Config Server
- Use a Spring Cloud Discovery Server
- Configure service binding
- Create and deploy a Spring Boot microservice
- Create and deploy a Spring Cloud Gateway
Prerequisites
Create an Azure Spring Cloud instance
Configure a Spring Cloud Config Server
- Add the repository URL, for example
https://github.com/<YOUR_USERNAME>/azure-spring-cloud-config
orgit@github.com:<YOUR_USERNAME>/azure-spring-cloud-config.git
. - Add your branch in
Label
. It defaults tomain
on GitHub, but older repositories or alternate Git providers might still usemaster
. - Click on Authentication and select HTTP Basic.
- The username is your GitHub login name.
- The password is the personal token we created in the previous section.
todo-service
application in your Azure Spring Cloud instance:This operation can take a few minutes, and will output a JSON document: copy the password attribute in that document, as we will use it later.
Now create a todos database in that server, and open up its firewall so that Azure Spring Cloud can access it:
az mysql db create \ --name "todos" \ --server-name ${SPRING_CLOUD_NAME}-mysql
Bind mySql database to the application now:
Azure Spring Cloud can automatically bind the MySQL database we created to our microservice.
- Go to Apps in your Azure Spring Cloud instance.
- Select the todo-service application.
- Go to Service bindings.
- Click on Create service binding.
- Give your binding a name, for example mysql-todos.
- In the Binding type list, select Azure database for MySQL.
- The Resource name should be the one of the MySQL database you created earlier.
- The Database name should be todos
- The User name should be spring@YOUR_DATABASE_NAME, with YOUR_DATABASE_NAME being the name of your database, that we set up earlier as ${SPRING_CLOUD_NAME}-mysql when creating it.
- The Password is the password attribute that we copied earlier, when creating the server.
Select Create, and your Spring Boot application will have the MySQL database connection set up.
Create a Spring Boot microservice
src/main/resources/application.properties
configuration file:Now that the application is deployed, it's time to test it!
- In the Azure portal, go to Apps in your Azure Spring Cloud instance.
- Verify todo-service has a Registered Instance that says 0/1. This shows that it is correctly registered in the Spring Cloud Service Registry.
- Select todo-service to have more information on the microservice.
- Copy/paste the "Test Endpoint" that is provided.
You can now use cURL to test the endpoint. Your test command should look like:
curl https://primary:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX@azure-spring-cloud-workshop.test.azuremicroservices.io/todo-service/default/
Build a Spring Cloud Gateway
Gateways are used to route public HTTP traffic to microservices:
- They handle the routing logic.
- They secure the access to the microservices (which will not be publicly available).
- They can also have Quality of Service (QoS) capabilities, like doing HTTP rate limiting.
Go to the project directory and copy followings to application.properties file:
spring.main.allow-bean-definition-overriding=true spring.cloud.gateway.discovery.locator.enabled=true
- The
spring.main.allow-bean-definition-overriding=true
part is to configure Spring Cloud Gateway to use the Spring Cloud Discovery Server bean configured in the Azure Spring Cloud Client library. - The
spring.cloud.gateway.discovery.locator.enabled=true
part is to configure Spring Cloud Gateway to use the Spring Cloud Service Registry to discover the available microservices.
todo-gateway
application in your Azure Spring Cloud instance. As this application is a gateway, we add the --assign-endpoint
flag so it is exposed publicly.Test the project in the cloud
- Go to Apps in your Azure Spring Cloud instance.
- Verify todo-gateway has a Registration status that says 1/1. This shows that it is correctly registered in the Spring Cloud Service Registry.
- Select todo-gateway to have more information on the microservice.
- Copy/paste the public URL that is provided (there is a "Test Endpoint" like for microservices, but the gateway is directly exposed on the Internet, so let's use the public URL). Keep this URL handy for subsequent sections.
As the gateway is connected to the Spring Cloud Service Registry, it should have automatically opened routes to the available microservices, with URL paths in the form of /MICROSERVICE-ID/**
: [The MICROSERVICE-ID must be in capital letters]
Test the todo-service
microservice endpoint by doing: curl https://XXXXXXXX-todo-gateway.azuremicroservices.io/TODO-SERVICE/
(replacing XXXXXXXX with the name of your Azure Spring Cloud instance)
Distributed tracing
We now have a complete microservices stack:
- A Spring Boot microservice, that stores its data in MySQL.
- A todo-gateway based on Spring Cloud Gateway.
However, even with only those two components, it already is quite challenging to monitor and study performance issues in our architecture.
To solve that issue, we're going to use Application Performance Monitoring (APM):
- Go to the Azure portal.
- Go to the overview page of your Azure Spring Cloud cluster and select Application Insights in the menu.
- This setting should already be on Enable.
- You'll have access to an application map, storing your tracing data.
Scale Spring Boot microservices
Spring Boot microservices and gateways running inside Azure Spring Cloud can be scaled vertically or horizontally:
- Vertical scaling means you increase (or decrease) the CPU and RAM of a given service.
- Horizontal scaling means you can add (or remove) nodes for a given service.
Scaling the "todo-service" microservice
- Go to the Azure portal.
- Go to the overview page of your Azure Spring Cloud cluster and select Apps in the menu.
- Select the todo-service application.
- Select Scale up in the left hand-side menu. You can now scale your service vertically, for example you can give it 2 CPUs and 4 Gb of RAM.
- Select Scale out in the left hand-side menu. You can also scale your service horizontally. For example, you can select your service and use Manual scale to have 2 instances of your service.
Let's try to build scrum masters/project managers/software architects/even a company with training AI models
The concept: The basic concept is to build trained AI model for each role separately in scalable fashion within a private cloud. As an examp...
-
Quarkus gRPC Service Implementation from the scratch Requirement In order to produce most reliable, fast and maintainable products we can us...
-
The concept: The basic concept is to build trained AI model for each role separately in scalable fashion within a private cloud. As an examp...
-
Problem Statement: Suppose the Government plans to issue up to $10,000 of Savings Bonds. Four individuals applied for a total of $18,000 of...