Welcome to Siva's Blog

~-Scribbles by Sivananda Hanumanthu
My experiences and learnings on Technology, Leadership, Domains, Life and on various topics as a reference!
What you can expect here, it could be something on Java, J2EE, Databases, or altogether on a newer Programming language, Software Engineering Best Practices, Software Architecture, SOA, REST, Web Services, Micro Services, APIs, Technical Architecture, Design, Programming, Cloud, Application Security, Artificial Intelligence, Machine Learning, Big data and Analytics, Integrations, Middleware, Continuous Delivery, DevOps, Cyber Security, Application Security, QA/QE, Automations, Emerging Technologies, B2B, B2C, ERP, SCM, PLM, FinTech, IoT, RegTech or any other domain, Tips & Traps, News, Books, Life experiences, Notes, latest trends and many more...
Showing posts with label system design. Show all posts
Showing posts with label system design. Show all posts

Sunday, April 3, 2022

A few cheat codes and tips from experienced Software Architects

 Having clean software architecture and staying conform to pre-defined design principles from start of the project is one of the best ways to avoid possible technical debt in the future of that software system. Clean Software Design is a key point for an effective software product.

Let us have a look at some important principles, rules, guidelines that ensure a clean software design:

Principles:

  1. Loose Coupling — if classes use each other, they are coupled together. The less classes are coupled, the easier is to change them.
  2. High Cohesion — degree to which elements of a whole belong together. Components of the class should be highly cohesive.
  3. Locality — Changes, maintenance, extensions are only local. This leads to no harming whole environment.
  4. Removeable — Software Components should be easily removeable.
  5. Small Components — software system should be only of small components ideally each doing only one task.

Class Design:

  1. Single Responsibility Principle (SRP) — class should do only one task.
  2. Open Closed Principle (OCP) — class should be extended not modified.
  3. Liskov Substitution Principle (LSP) — child classes must be able to replace their super classes.
  4. Dependency Inversion Principle (DIP) — dependeny is reversed: high level components are free of low-level components.
  5. Interface Segregation Principle (ISP) — interfaces should be small: classes should not implement unnecessary methods.

Cohesion Principles:

  1. Release Reuse Equivalency Principle (RREP) — only together releaseable components should be bundled together.
  2. Common Closure Principle (CCP) — classes that change together should be bundled together.
  3. Common Reuse Principle (CRP) — classes that are used together should be bundled together.

Coupling Principles:

  1. Acyclic Dependencies Principle (ADP) — no dependency cycles.
  2. Stable Dependencies Principle (SDP) — depend on direction of stability.
  3. Stable Abstractions Principle (SAP) — the more abstract, the more stable.

High-Level Architecture:

  1. Keep Configurable Data at High Levels — constants or config datas should be kept in high level.
  2. Don’t Be Inconsistent— have a convention, principle, rule or guidelines and always follow them.
  3. Prefer Polymorphism To If/Else or Switch/Case.
  4. Separate Multi-Threading Code — isolate multi-thread from rest of the code.
  5. Only one level of Abstraction per layer — stay conform to existing abstraction layers.
  6. Fields Not Defining State — fields holding data that does not belong to the state of the instance but are to hold temporary data. Use local variables or extract to a class abstracting the performed action.
  7. Micro Layers — avoid unnecessary design layers.
  8. Singletons / Service Locator — Make use of dependency injection.
  9. Base Classes Depending On Their Derivatives — Base classes should work with any derived class.
  10. Feature Envy — The methods of a class should be interested in the variables and functions of the class they belong to, and not the variables and functions of other classes. Using accessors and mutators of some other object to manipulate its data, is envying the scope of the other object ©.
  11. Unused Coupling — avoid unused dependencies, be greedy.
  12. Hidden Coupling — make sure that order of calls to different methods are correct.
  13. Transitive Navigation — (Law of Demeter), write isolated code. Classes should have access to only its direct dependencies.

Environment:

  1. Project Build Requires Only One Step.
  2. Executing Tests Requires Only One Step.
  3. Source Control System — Always use a source control system.
  4. Continuous Integration — Assure integrity with Continuous Integration.
  5. Overridden Logs— Do not override warnings, errors, exception handling

Saturday, January 9, 2021

API Gateway vs. Service Mesh

 Service Mesh "How is it different from an API gateway?" It's a good question. The overlap between API gateway and service mesh patterns is significant. They can both handle service discovery, request routing, authentication, rate limiting, and monitoring, but there are differences in architectures and intentions. A service mesh's primary purpose is to manage internal service-to-service communication, while an API Gateway is primarily meant for external client-to-service communication.

Image title

Do You Need Both?

You may be wondering if you need both an API gateway and a service mesh.  Today you probably do, but as service mesh evolves, we believe it will incorporate much of what you get from an API gateway today.

The main purpose of an API gateway is to accept traffic from outside your network and distribute it internally. The main purpose of a service mesh is to route and manage traffic within your network. A service mesh can work with an API gateway to efficiently accept external traffic then effectively route that traffic once it's in your network. The combination of these technologies can be a powerful way to ensure application uptime and resiliency while ensuring your applications are easily consumable.

In a deployment with an API gateway and a service mesh, incoming traffic from outside the cluster would first be routed through the API gateway, then into the mesh. The API gateway could handle authentication, edge routing and other edge functions, while the service mesh provides fine-grained observability of and control of your architecture.

The interesting thing to note is that service mesh technologies are quickly evolving and are starting to take on some of the functions of an API gateway. A great example is the introduction of the Istio v1alpha3 routing API which is available in Aspen Mesh 1.0. Prior to this, Istio had used Kubernetes ingress control which is pretty basic so it made sense to use an API gateway for better functionality. But, the increased functionality introduced by the v1alpha3 API has made it easier to manage large applications and to work with protocols other than HTTP, which was previously something an API gateway was needed to do effectively.

What The Future Holds

The v1alpha3 API provides a good example of how a service mesh is reducing the need for API gateway capabilities. As the cloud-native space evolves and more organizations move to using Docker and Kubernetes to manage their microservice architectures, it seems highly likely that service mesh and API gateway functionality will merge. In the next few years, we believe that standalone API gateways will be used less and less as much of their functionality will be absorbed by service mesh.

References:

https://dzone.com/articles/api-gateway-vs-service-mesh

https://konghq.com/blog/the-difference-between-api-gateways-and-service-mesh/

https://medium.com/microservices-in-practice/service-mesh-vs-api-gateway-a6d814b9bf56

Choosing between the tools is at https://medium.com/@mahesh.mahadevan/my-experiences-with-api-gateways-8a93ad17c4c4

Wednesday, December 30, 2020

Top 10 must-know Kubernetes design patterns

 Top 10 must-know Kubernetes design patterns

Here are the must-know top 10 design patterns for beginners synthesized from the Kubernetes Patterns book. Getting familiar with these patterns will help you understand foundational Kubernetes concepts, which in turn will help you in discussions and when designing Kubernetes-based applications.

There are many important concepts in Kubernetes, but these are the most important ones to start with:

Top 10 Kubernetes Design Patterns laid out in a graphic

Source: Kubernetes Patterns

To help you understand, the patterns are organized into a few categories below, inspired by the Gang of Four’s design patterns.

Foundational patterns

These patterns represent the principles and best practices that containerized applications must comply with in order to become good cloud-native citizens. Regardless of the application’s nature, you should aim to follow these guidelines. Adhering to these principles will help ensure that your applications are suitable for automation on Kubernetes.

Health Probe pattern

Health Probe dictates that every container should implement specific APIs to help the platform observe and manage the application in the healthiest way possible. To be fully automatable, a cloud-native application must be highly observable by allowing its state to be inferred so that Kubernetes can detect whether the application is up and ready to serve requests. These observations influence the life-cycle management of Pods and the way traffic is routed to the application.

Predictable Demands pattern

Predictable Demands explains why every container should declare its resource profile and stay confined to the indicated resource requirements. The foundation of successful application deployment, management, and coexistence on a shared cloud environment is dependent on identifying and declaring the application’s resource requirements and runtime dependencies. This pattern describes how you should declare application requirements, whether they are hard runtime dependencies or resource requirements. Declaring your requirements is essential for Kubernetes to find the right place for your application within the cluster.

Automated Placement patterns

Automated Placement explains how to influence workload distribution in a multi-node cluster. Placement is the core function of the Kubernetes scheduler for assigning new Pods to nodes satisfying container resource requests and honoring scheduling policies. This pattern describes the principles of Kubernetes’ scheduling algorithm and the way to influence the placement decisions from the outside.

Structural patterns

Having good cloud-native containers is the first step, but not enough. Reusing containers and combining them into Pods to achieve the desired outcome is the next step. The patterns in this category are focused on structuring and organizing containers in a Pod to satisfy different use cases. The forces that affect containers in Pods result in these patterns.

Init Container pattern

Init Container introduces a separate life cycle for initialization-related tasks and the main application containers. Init Containers enable separation of concerns by providing a separate life cycle for initialization-related tasks distinct from the main application containers. This pattern introduces a fundamental Kubernetes concept that is used in many other patterns when initialization logic is required.

Sidecar patterns

Sidecar describes how to extend and enhance the functionality of a pre-existing container without changing it. This pattern is one of the fundamental container patterns that allows single-purpose containers to cooperate closely together.

Behavioral patterns

These patterns describe the life-cycle guarantees of the Pods ensured by the managing platform. Depending on the type of workload, a Pod might run until completion as a batch job or be scheduled to run periodically. It might run as a daemon service or singleton. Picking the right life-cycle management primitive will help you run a Pod with the desired guarantees.

Batch Job patterns

Batch Job describes how to run an isolated, atomic unit of work until completion. This pattern is suited for managing isolated atomic units of work in a distributed environment.

Stateful Service patterns

Stateful Service describes how to create and manage distributed stateful applications with Kubernetes. Such applications require features such as persistent identity, networking, storage, and ordinality. The StatefulSet primitive provides these building blocks with strong guarantees ideal for the management of stateful applications.

Service Discovery pattern

Service Discovery explains how clients can access and discover the instances that are providing application services. For this purpose, Kubernetes provides multiple mechanisms, depending on whether the service consumers and producers are located on or off the cluster.

Higher-level patterns

The patterns in this category are more complex and represent higher-level application management patterns. Some of the patterns here (such as Controller) are timeless, and Kubernetes itself is built on top of them.

Controller pattern

Controller is a pattern that actively monitors and maintains a set of Kubernetes resources in a desired state. The heart of Kubernetes itself consists of a fleet of controllers that regularly watch and reconcile the current state of applications with the declared target state. This pattern describes how to leverage this core concept for extending the platform for our own applications.

Operator pattern

An Operator is a Controller that uses a CustomResourceDefinitions to encapsulate operational knowledge for a specific application in an algorithmic and automated form. The Operator pattern allows us to extend the Controller pattern for more flexibility and greater expressiveness. There are an increasing number of Operators for Kubernetes, and this pattern is turning into the major form of operating complex distributed systems.

Summary

Today, Kubernetes is the most popular container orchestration platform. It is jointly developed and supported by all major software companies and offered as a service by all of the major cloud providers. Kubernetes supports both Linux and Windows systems, plus all major programming languages. This platform can also orchestrate and automate stateless and stateful applications, batch jobs, periodic tasks, and serverless workloads. The patterns described here are the most commonly used ones from a broader set of patterns that come with Kubernetes as shown below.

Kubernetes Patters organized in different categories

Kubernetes is the new application portability layer and the common denominator among everybody on the cloud. If you are a software developer or architect, the odds are that Kubernetes will become part of your life in one form or another. Learning about the Kubernetes patterns described here will change the way you think about this platform. I believe that Kubernetes and the concepts originating from it will become as fundamental as object-oriented programming concepts.

The patterns here are an attempt to create the Gang of Four design patterns, but for container orchestration. Reading this article must not be the end, but the beginning of your Kubernetes journey. Happy kubectl-ing!


Reference: 

https://developers.redhat.com/blog/2020/05/11/top-10-must-know-kubernetes-design-patterns/

https://k8spatterns.io/

https://github.com/k8spatterns/examples

Sunday, July 26, 2020

Blockchain blocks and Merkle trees

A firm introduction on the blockchain can be found from here at https://blockgeeks.com/guides/what-is-blockchain-technology/ or https://en.wikipedia.org/wiki/Blockchain as a refresher... Now, quickly let me jump onto how these blocks data are getting verified with the right synchronization across all the nodes or blocks? How can we check the consistency, data verification, and data synchronization, etc?

The data structure behind it can be Merkle trees, Merkle tree also known as a hash tree is a data structure used for data verification and synchronization. It is a tree data structure where each non-leaf node is a hash of its child nodes. All the leaf nodes are at the same depth and are as far left as possible. It maintains data integrity and uses hash functions for this purpose.

The more uses of these Merke trees are below:
  1. If you wanted to do data verifications across your distributed systems
  2. DLTs (Distributed Ledger Technologies) such as Bitcon, Ethereum
  3. Well known distributed databases like Apache Cassandra
  4. Global supply chain
  5. Health care industry etc
You may find more details of the Merkle trees along with sample code implementation can be found from the following sources:
https://www.geeksforgeeks.org/introduction-to-merkle-tree/
https://github.com/quux00/merkle-tree
https://medium.com/@vinayprabhu19/merkel-tree-in-java-b45093c8c6bd
https://www.codeproject.com/Articles/1176140/Understanding-Merkle-Trees-Why-use-them-who-uses-t




Friday, July 17, 2020

The C4 model for visualizing software architecture

The C4 model for visualizing software architecture

What is C4?
Context, Containers, Components, and Code

What tools can I use? How to create?
There are many tools available and can be used, and my favorite is http://draw.io/

Why one should use it?
Usually, there are many ways one can visualize the software architecture diagrams including UML, and yet, if you are going in a faster and agile of handling software architecture and wanted to visualize easily, then you can go for the C4 model

Where it is widely used?
To communicate your software architecture diagrams effectively in fast-paced environments

You wanted to know more, then go ahead and read more at https://c4model.com/

Friday, June 19, 2020

The more highly available system means that the less downtime you have to deal with

The more highly available system means that the less downtime you have to deal with...

Imagine,

The five nines, 99.999 availability means ~5 mins of downtime a year
The four nines, 99.99 availability means ~ 50 mins of downtime a year
The three nines, 99.9 availability means ~9 hours of downtime a year
The two nines, 99 availability means roughly 3 and half days of downtime a year

So, why are we concerned about the downtime? the more downtime you have means the less you attract your customers as I presume most of the systems or applications are accessible 24/7 and it means that round the clock!

We might be thinking that - oh, yeah - we have good ample of downtime in our hands to deal with it, but believe me, if you don't design the system very well with right practices and processes in place then it would be very hard to even achieving the two nines availability too, so, you have to really work very hard and smart to deal with it in an effective manner.

Some tips to utilize the downtime effectively for your systems or platforms are:

  1. Make sure to eliminate any single point of failures; Especially handing with the third party API endpoints or dependent systems those are not in your control by having right retry frameworks and circuit breaker patterns
  2. Observability and Monitoring with clear alerts and notifications in place
  3. Have an efficient CI/CD pipelines with right checks on various stages of your configured environment to stop promoting the bad code (faulty code which has issues, and it can be performance issues as well)
  4. Have well-defined deployments and the changed code propagation with
    1. Blue-green deployments (having two identical production environments, one is blue and other one is green)
    2. Canary deployments (by routing smaller traffic to the new changes and slowly increase the traffic)
  5. Encourage A/B testing within your product features release where you are not sure on some of the features; also, promote canary releases too
  6. Lastly, try to have a very diligent process by imagining all dimensions how your system can fail with scenarios(and that has come from your proactive resiliency testing activities) so that you have right tools to troubleshoot, tune and respond for any unknown hardware or network failures 

Monday, October 1, 2018

Do you want to access your computer and terminal via the Web?

Do you want to access your computer and terminal via the Web?

I mean via your web browser for the right troubleshooting and do everything via HTTP

Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH.

https://guacamole.apache.org/

GoTTY - Share your terminal as a web application, GoTTY is a simple command-line tool that turns your CLI tools into web applications.

https://github.com/yudai/gotty

Sunday, December 28, 2014

All in one : Python

A curated list of awesome Python frameworks, libraries, software, and resources

Reference:

https://github.com/vinta/awesome-python

Sunday, June 9, 2013

We all know SOA, but what is ROA?

We all know SOA(that is Service Oriented Architecture), but what is ROA?

ROA stands for Resource-Oriented Architecture, and what are the Resources here? The resources are nothing but your RESTful services or interfaces. This would become a paradigm shift in the overall web services world very soon and every company would adapt to the ROA instead of SOA to gain more traction in their way of doing businesses and services.

Basics of  RESTful services or interfaces:

REST is an architecture style for designing networked applications. It stands for REpresentational State Transfer. 

What is not REST?

  • A language
  • A framework
  • A brand
  • Software that you can download and make it run.
  • A standard (W3C hasn't accepted, so it continues as open style)

REST constraints

As REST creator, Roy Fielding describes in his doctoral dissertation, it was conceived as a whole sets of needs, shaped by the constraints of the environment in which this system was going to be implemented. Such constraints are:

  • Client-Server
  • Uniform Interface
  • Stateless
  • Cacheable
  • Layered System
  • Code on demand (optional)

Some definitions before

State

A state is that which the server application cares about to fulfill the request. This is the chunk of information that is sent by the server in every response.

Resource

A resource is data that defines a model representation. This might be the stored data in the database.

Note, that, a state is a piece of information that depends on the request and the client that is asking for; while the resource is information that is constant through all clients (of course until it needs to be updated).

Idempotence

In terms of computer science, this term has a different meaning. It describes an operation that will produce the same result whether it is being called once or many times. In other words, making multiple identical requests has the same effect as making a single one. Imagine a client asking a server to update the resource, setting its property to the value of 20. No matter how many times you ask this. You'll have the same effect on the database.

Safety

Speaking of RESTful approach, safety means the ability of a method to not change the state of a resource in the server. This means, all methods that are safety doesn't alter the information (database). Consequently, clients can make safe requests repeatedly without worry of side effects on the server.

Client-Server

The web operates in this way: where there is a web server delivering content, that is being interpreted by a browser or a mobile app. In this case, the server is usually the web application, and the client is the browser, or mobile app. In this scenario, the information flow happens in one way: The client does a request to the server, which after processing such request, delivers a response.

Uniform Interface

This constraint defines that the interface between any server, and all possibilities of clients, should be the same. This decouples the architecture between client and server, giving the ability to both to evolve separately.

Stateless

Here it comes what REST means. Representational State Transfer means that each request has to carry with the necessary state to handle the transaction. This releases the server from keeping a state of information between multiple requests. Are you familiar with the concept of SESSION in web development ? REST avoids the existence of it. And because of this, the server gets the ability to scale better.

Cacheable

This constraint says that each response must define implicitly or explicitly, whether it is a cacheable resource, or not. By telling a client that such content is cacheable, it optimizes the performance of communication, since the client will avoid unnecessary requests for static data.

Layered System

This says that from the server-side, scalability may be improved in such way that the client won't notice whether it is dealing in one server or an intermediary app. That let the server side infrastructure to escalate through load balancing, shared caches, and security middlewares.

Code on demand (optional)

This means that the server might also delivers logic to the client, such as javascript content that might be interpreted by the client. This is optional, and I think is nowadays not used, since the appearance of Single Page Apps.

2. REST How-to

Principles

Know the best RESTful practices from the community.

1. Use meaningful HTTP verbs.

You know them: GET, POST, PUT, DELETE. Such verbs already mean an intention, and the purpose of REST principles is to use this as an advantage to set clarity for t he API.

2. Sensible resource names.

In the old times of web development, a resource used to accept parameters from long query strings, such as /api?model=user&id=123. By following this principle, the URI (also called resource name) shoud be as well meaninful as the HTTP verb. So rewriting the previous URI to a meaningful one, would be /user/123.

3. XML and JSON

That's up to the necessities of the client. If you're going to provide a public API, having both is a good idea, since you have a broad scope of clients that can interact with your app. But we suggest to favor JSON over XML. This is because the simplicity of its nature as a data container. Also, since most of the clients are browsers, JSON is javascript syntax, which makes perfect to be parsed by the client side. If you're going to render XML, avoid namespaces, and think of XML as a data container, which is the purpose of the API.

4. Create Fine-Grained Resources

Instead of starting with complex services, focus on basic, simple resources, and provide CRUD operations on them. Additionally you will add complex services over that system.

5. Idempotence for PUT and DELETE

This means that by sending a request with the same state (data) to the server, you'll have the same effect on the domain/database.

6. Safety for HEAD, GET, OPTIONS and TRACE

These methods are defined to be safe, this means, to not alter the state in the server.

HTTP Verbs

Technically, there are 8 HTTP Methods. The most used in RESTful APIs are only 4 (GET, POST, PUT and DELETE). They cover CRUD operations on a resource.

  1. GET
  2. POST
  3. PUT
  4. DELETE
  5. OPTIONS
  6. HEAD
  7. TRANCE
  8. CONNECT

1. GET

GET is used to retrieve information from the server, specifically information of a resource. If the request goes well, it returns a 200 code. Otherwise, it might return an error code, like 404 or 400

Examples:

# Gets a list of all users
GET /api/users
# Gets details for user with id = 23
GET /api/users/23
# Gets a list of all orders belonging to user with id = 23
GET /api/users/23/orders

2. POST

POST is used for creating a resource. It accepts usually a JSON body in the request. This data is the state for the resource that is going to be created. If the execution goes well, it returns a status code 201, with a location header with the link to the newly created resource. The POST operation is not safe, since it affects the state of information. It is also not an idempotent operation, since every time a resource creation is requested, the id attribute will be auto-incremented, making the effect of this operation, unique every time.

Examples:

# Inserts a user
POST /api/users
# body
{
  name: "User"
}

3. PUT

PUT is used for updating a resource. It accepts usually a JSON body which contains the data of the resource that will be updated. On succesful execution, it returns a status code 200. PUT is not a safe operation, since it affects the state of the resource in the server information. However, PUT is encouraged to be an idempotent operation. This is, by knowing the id of the resource that will be updated, and having certain values that will be written, every operation will cause the same effect on the resource status in the server.

Examples:

# Updates a user
PUT /api/users/23
# body
{
  name: "User number 23"
}

4. DELETE

DELETE operation is used for deleting a resource identified by a URI. This is not a safe operation, since it affects the state of the resource in the server. If the operation goes well, it responds with a satus code of 200. DELETE operation is idempotent. This is, by calling this operation the first time, the resource will be deleted from the server information storage (database), and by calling the next times, the response should be the same: the resource is gone.

Examples:

# Deleting a user
DELETE /api/users/delete/23

Methods Cheatsheet

HTTP MethodResource OperationExample URIResponse codeLocation HeaderSafeIdempotent
GETFetch/api/users, /api/users/{id}200NoYesNo
POSTCreate/api/users201YesNoNo
PUTUpdate/api/users/{id}200NoNoYes
DELETEDelete/api/users/{id}200NoNoYes

Response Status Codes

We will cover the most common codes here. If you want to check the full list, you can go to MDN page.

  • 2xx Success
  • 3xx Redirect
  • 4xx User error
  • 5xx Server error

2xx Success codes

  • 200 OK (default code)
  • 201 Created (Response for POST requests)
  • 202 Accepted (Response for DELETE requests)

4xxx Error codes

  • 400 Bad request (generic)
  • 401 Unauthorized
  • 404 Not found (Bad URL, resource not found)
  • 405 Method not allowed (wrong HTTP method)
  • 409 Conflict

3. Examples

When you have your api in the same domain that your web app

// prefix of /api to encapsulate API into one set of controller/routes
GET /api/users
GET /api/users/{id}

//another controllers in the webapp, traditional HTML response
GET /users
GET /users/{id}

When you have a specific domain for API, but different versions ov if

// API v1
GET /v1/users
GET /v1/users/{id}

// API v2.3
GET /v2.3/users
GET /v2.3/users/{id}

One domain, simple URI

GET /users
GET /users/{id}

Nested resources

//users is the main resource
GET /users
GET /users/{id}

//contracts is a sub resource of users
GET /users/{id}/contracts
GET /users/{id}/contracts/{contract_id}

Valid Methods for URIs

GET /users
GET /users/{id}
POST /users
PUT /users/{id}
DELETE /users/{id}

Invalid Methods for URIs

// you cannot create by specifying a specific resource
POST /users/{id}

// You cannot update state for a URI that doesn't represent a specific resource
PUT /users

// You cannot delete a resource if you no provide its specific URI
DELETE /users