Saturday, August 6, 2022

Angular Documentation

 When I tried to read about the an already written Angular app, I felt difficult to know all components, services, directives. 

The idea of generating a documentation for angular app came in mind and voila, there are already some products which generate Angular app documentation for a product. The product I used is called compodoc. 

To install compodoc, simply run

 npm install --save-dev @compodoc/compodoc

Then update your package.json

"scripts": {
    "compodoc": "compodoc -p tsconfig.json"
}

Then you can run compodoc as a normal npm script using

npm run compodoc

Monday, July 25, 2022

Redis - Caching in .NET using C#

Performance optimization drives us to implement a caching mechanism in our system. One of the best way is to use Caching to store frequent data.

Caching is the way of storing data in a temporary storage location, so that data retrieval can be made more efficient.


Usually, we put that kind of data in cache that changes infrequently. 

For example, to get a person’s Avatar you might need a trip to the database. Instead of performing that trip every time, we will save that Avatar in the cache, pulling it from memory every time you need it.

Benefits of Caching:

1. Reduces the load on server by reducing the round trips to the server

2. Increases performance by making application more responsive. 

Types of Cache:

  • In-Memory Cache is used for when you want to implement cache in a single process. When the process dies, the cache dies with it. If you’re running the same process on several servers, you will have a separate cache for each server.

  • Persistent in-process Cache is when you back up your cache outside of process memory. It might be in a file, or in a database. This is more difficult, but if your process is restarted, the cache is not lost. Best used when getting the cached item is expansive, and your process tends to restart a lot.

  • Distributed Cache is when you want to have shared cache for several machines. Usually, it will be several servers. With a distributed cache, it is stored in an external service. This means if one server saved a cache item, other servers can use it as well. Services like Redis are great for this.
To make distributed caches easy to use and keep them fast, they typically employ a “NoSQL” key/value access model and store values as serialized objects

Tools for Distributed Cache :
1. MemCached
2. NCache
3. 


Distributed cache with Redis:
A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.




The use of Redis is widespread in distributed caching scenarios. Redis is an in-fast-memory datastore, it is opensource and is of key-value type. 

It provides response times of less than one millisecond, allowing millions of requests per second for each real-time application in a variety of fields.
If the infrastructure of your application is based on an AWS cloud, the service Elastic Cache -> Redis Cache is available, and it can be configured from your subscription.

To use the distributed cache on Redis, the installation of the package Microsoft.Extensions.Caching.Redis is necessary.

Package: Microsoft.Extensions.Caching.StackExchangeRedis

Code Links:



Monday, April 4, 2022

Getting credentials from AWS

 There are various ways to get the credentials from AWS:

I have been using AWS SDK.NET and here is the code to get credentials using IAM role. To run this code, make sure you are running this application on EC2 instance. 


     private async Task<Stream> GetS3BucketFileIAM(string filepath)

        {

            var credentials = FetchCredentials();


            var request = new GetObjectRequest

            {

                BucketName = _bucketName,

                Key = filepath

            };


            var config = new AmazonS3Config

            {

                RegionEndpoint = RegionEndpoint.GetBySystemName(_regionName)

            };


            var s3Client = new AmazonS3Client(credentials.AccessKey, credentials.SecretKey, credentials.Token, config);


            var response = await s3Client.GetObjectAsync(request);


            return response.ResponseStream;

        }


        private ImmutableCredentials FetchCredentials()

        {

            var securityCredentials = EC2InstanceMetadata.IAMSecurityCredentials;

            if (securityCredentials == null)

                throw new AmazonServiceException("Unable to get IAM security credentials from EC2 Instance Metadata Service.");


            string firstRole = null;

            foreach (var role in securityCredentials.Keys)

            {

                firstRole = role;

                break;

            }


            if (string.IsNullOrEmpty(firstRole))

                throw new AmazonServiceException("Unable to get EC2 instance role from EC2 Instance Metadata Service.");


            var metadata = securityCredentials[firstRole];

            if (metadata == null)

                throw new AmazonServiceException("Unable to get credentials for role \"" + firstRole + "\" from EC2 Instance Metadata Service.");


            return new ImmutableCredentials(metadata.AccessKeyId, metadata.SecretAccessKey, metadata.Token);

        }

Other way to use credentials is from Profile if someone has already installed AWS CLI

        private static AWSCredentials GetDefaultAwsCredentialsFromProfile()

        {

            var credentialProfileStoreChain = new CredentialProfileStoreChain();

            if (credentialProfileStoreChain.TryGetAWSCredentials("default", out var defaultCredentials))

                return defaultCredentials;


            return null;

        }



Helpful threads:

c# - How to set credentials on AWS SDK on NET Core? - Stack Overflow

Credential Loading and the AWS SDK for .NET (Deep Dive) - Steve Gordon - Code with Steve (stevejgordon.co.uk)

 

How to get metadata.

HowTo: Get Amazon EC2 Instance Metadata - Dowd and Associates

Authenticating to AWS with Instance Metadata | by Yevgeniy Brikman | Gruntwork

AWS Access Keys - A Reference - Nick Jones (nojones.net)

Doing AWS STS the right way. - Short Term Security · Archer Imagine

Credential and profile resolution - AWS SDK for .NET (amazon.com)


Thursday, January 20, 2022

Clean Code architecture

 The Clean Architecture is the system architecture guideline proposed by Robert C. Martin (Uncle Bob) derived from many architectural guidelines like Hexagonal Architecture, Onion Architecture, etc... over the years.


Follow the video provided by Jason Taylor 

Clean Architecture with ASP.NET Core 3.0 • Jason Taylor • GOTO 2019 - YouTube

https://jasontaylor.dev/clean-architecture-getting-started

GitHub - jasontaylordev/CleanArchitecture: Clean Architecture Solution Template for .NET 6



Sunday, January 9, 2022

Terraform

 Terraform

In today's standup call, heard someone talking about Terraform. 


Thursday, December 30, 2021

CSV Helper

 

CsvHelper:

A .NET library for reading and writing CSV files. Extremely fast, flexible, and easy to use.


Github:
https://joshclose.github.io/CsvHelper/


Reading a csv file :

public class Foo { [Name("id")] public int Id { get; set; } [Name("name")] public string Name { get; set; } }

using (var reader = new StreamReader(@"c:\projects\data.csv")) using (var csv = new CsvReader(reader, config)) { var records = csv.GetRecords<Foo>(); }

Writing to CSV:

using (var writer = new StreamWriter("c:\projects\data.csv")
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) { csv.WriteRecords(records); }


Utility method for refactoring code for getting all the records from CSV:

private IEnumerable<T> ReadStream<T, TMap>(string csvPath) where TMap: ClassMap { IEnumerable<T> records; using (var reader = new StreamReader(this.awsS3Service.GetS3BucketFile(csvPath))) { using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { csv.Configuration.Delimiter = "|"; csv.Configuration.RegisterClassMap<TMap>(); records = csv.GetRecords<T>().ToList(); } } return records; }


Call above method using :
this.ReadStream<BrandFile, BrandFileCSVMap>(s3FilePath)

public class BrandFile { public int BrandId { get; set; } public string BrandName { get; set; } public string BrandWebsite { get; set; } public string BrandLogoURL { get; set; } }

public sealed class BrandFileCSVMap: ClassMap<BrandFile> { public BrandFileCSVMap() { AutoMap(CultureInfo.InvariantCulture); } }


Saturday, November 13, 2021

Fundamentals of React

Why React: It is a JS library by Facebook to create web user interfaces. 

Features of React:
1. Virtual DOM : best for performance. 
2. Reactive Updates
3. Writing HTML in JS code rather than code templating (code placeholders and if -switches)

Building blocks of React:

1. Components - Functional components and Class components
2. Props and States
3. JSX
4. React Hooks
5. Redux (Flux)

Playgrounds:
https://jscomplete.com/playground



JSX: Javascript XML



equivalent to :

React.createElement(
Sum, {a:3, b:4}, null
)

React Data flow:

Ways to create React components:

1. createClass
2. ES classes
3. Functions
4. Arrow functions


We have used create-react-app introduced by Facebook which takes away 70% of boilerplate setup. 
This is a wrapper so you don’t need to worry about environment setups, Webpack configurations, bundle properties, dev server and so much more. 
All of this headache is handled by Facebook so all your worry is around building application.
create-react-app provides us complete environment setup with React but these days an application need more than just React. Applications are growing fast and stuff like state management goes out of hand quickly.
Create a component :
1. Using the createClass factory
var Todolist = React.createClass({

    render: function() {
        return (
        <div></div>
        );
    }
})



2. Extending React.Component

import React from 'react';

export default class Todolist extends React.Component
{
    render() {
        return (
            <div>
            <h1 className="header">React Component</h1>
            </div>
        )
    }
}

There are two ways to pass data to a render() method using the React API
1. Props
2. State

Lets create a TODO List component :

import React from 'react';
import TodoItem from './TodoItem';

export default class Todolist extends React.Component
{
    render() {

        let todoItemsData = [
            {
                id: 1,
                title: 'Learn Javascript',
                desc: 'Lorem ipsum description 1',
                priority:'high',
                date: 'Jun 1, 2012'
            },
            {
                id: 2,
                title: 'Learn React',
                desc: 'Lorem ipsum description 2',
                priority:'medium',
                date: 'Jul 1, 2015'
            },
            {
                id: 3,
                title: 'Build a React App',
                desc: 'Lorem ipsum description 3',
                priority:'low',
                date: 'Jun 1, 2011'
            }
        ];

        return (
<div class="container page-todo bootstrap snippets bootdeys">
<div class="col-sm-7 tasks">
    <div class="task-list">
        <h1>TODO List</h1>

        {todoItemsData.map(item => (
                <TodoItem key={item.id}  data={item} />
            ))}
 
        <div class="clearfix"></div>        
    </div>      
</div>
</div>
        )
    }
}

import React from 'react';

export default class Todolist extends React.Component
{
    constructor(props)
    {
        super(props);
        console.log(props.data);
       
    }

    render() {
        let priorityClasses = ['priority task', this.props.data.priority].join(' ');

        return (
            <div class={priorityClasses}>
                  <div class="checkbox">
                    <input type="checkbox" />
                 </div>
            <div class="desc">
                <div class="title">{this.props.data.title}</div>
                <div>{this.props.data.desc}</div>
            </div>
            <div class="time">
                <div class="date">{this.props.data.date}</div>
            </div>
        </div>
        )
    }
}


Now use this component :
import logo from './logo.svg';
import './App.css';
import Todolist from './Todolist';


function App() {
  return (
    <div className="App">
<Todolist />
    </div>
  );
}

export default App;


CSS used in App.css

body{
  margin-top:10px;
  background:#eee;
  }
 
  .page-todo .tasks {
      background: #fff;
      padding: 0;
      border-right: 1px solid #d1d4d7;
      margin: -30px 15px -30px -15px
  }
 
  .page-todo .task-list {
      padding: 30px 15px;
      height: 100%
  }
 
  .page-todo .graph {
      height: 100%
  }
 
  .page-todo .priority.high {
      background: #fffdfd;
      margin-bottom: 1px
  }
 
  .page-todo .priority.high span {
      background: #f86c6b;
      padding: 2px 10px;
      color: #fff;
      display: inline-block;
      font-size: 12px
  }
 
  .page-todo .priority.medium {
      background: #fff0ab;
      margin-bottom: 1px
  }
 
  .page-todo .priority.medium span {
      background: #f8cb00;
      padding: 2px 10px;
      color: #fff;
      display: inline-block;
      font-size: 12px
  }
 
  .page-todo .priority.low {
      background: #cfedda;
      margin-bottom: 1px
  }
 
  .page-todo .priority.low span {
      background: #4dbd74;
      padding: 2px 10px;
      color: #fff;
      display: inline-block;
      font-size: 12px
  }
 
  .page-todo .task {
      border-bottom: 1px solid #e4e5e6;
      margin-bottom: 1px;
      position: relative
  }
 
  .page-todo .task .desc {
      display: inline-block;
      width: 75%;
      padding: 10px 10px;
      font-size: 12px
  }
 
  .page-todo .task .desc .title {
      font-size: 18px;
      margin-bottom: 5px
  }
 
  .page-todo .task .time {
      display: inline-block;
      width: 15%;
      padding: 10px 10px 10px 0;
      font-size: 12px;
      text-align: right;
      position: absolute;
      top: 0;
      right: 0
  }
 
  .page-todo .task .time .date {
      font-size: 18px;
      margin-bottom: 5px
  }
 
  .page-todo .task.last {
      border-bottom: 1px solid transparent
  }
 
  .page-todo .task.high {
      border-left: 2px solid #f86c6b
  }
 
  .page-todo .task.medium {
      border-left: 2px solid #f8cb00
  }
 
  .page-todo .task.low {
      border-left: 2px solid #4dbd74
  }
 
  .page-todo .timeline {
      width: auto;
      height: 100%;
      margin: 20px auto;
      position: relative
  }
 
  .page-todo .timeline:before {
      position: absolute;
      content: '';
      height: 100%;
      width: 4px;
      background: #d1d4d7;
      left: 50%;
      margin-left: -2px
  }
 
  .page-todo .timeslot {
      display: inline-block;
      position: relative;
      width: 100%;
      margin: 5px 0
  }
 
  .page-todo .timeslot .task {
      position: relative;
      width: 44%;
      display: block;
      border: none;
      -webkit-box-sizing: content-box;
      -moz-box-sizing: content-box;
      box-sizing: content-box
  }
 
  .page-todo .timeslot .task span {
      border: 2px solid #63c2de;
      background: #e1f3f9;
      padding: 5px;
      display: block;
      font-size: 11px
  }
 
  .page-todo .timeslot .task span span.details {
      font-size: 16px;
      margin-bottom: 10px
  }
 
  .page-todo .timeslot .task span span.remaining {
      font-size: 14px
  }
 
  .page-todo .timeslot .task span span {
      border: 0;
      background: 0 0;
      padding: 0
  }
 
  .page-todo .timeslot .task .arrow {
      position: absolute;
      top: 6px;
      right: 0;
      height: 20px;
      width: 20px;
      border-left: 12px solid #63c2de;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent;
      margin-right: -18px
  }
 
  .page-todo .timeslot .task .arrow:after {
      position: absolute;
      content: '';
      top: -12px;
      right: 3px;
      height: 20px;
      width: 20px;
      border-left: 12px solid #e1f3f9;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent
  }
 
  .page-todo .timeslot .icon {
      position: absolute;
      border: 2px solid #d1d4d7;
      background: #2a2c36;
      -webkit-border-radius: 50em;
      -moz-border-radius: 50em;
      border-radius: 50em;
      height: 30px;
      width: 30px;
      top: 0;
      left: 50%;
      margin-left: -17px;
      color: #fff;
      font-size: 14px;
      line-height: 30px;
      text-align: center;
      text-shadow: none;
      z-index: 2;
      -webkit-box-sizing: content-box;
      -moz-box-sizing: content-box;
      box-sizing: content-box
  }
 
  .page-todo .timeslot .time {
      background: #d1d4d7;
      position: absolute;
      -webkit-border-radius: 4px;
      -moz-border-radius: 4px;
      border-radius: 4px;
      top: 1px;
      left: 50%;
      padding: 5px 10px 5px 40px;
      z-index: 1;
      margin-top: 1px
  }
 
  .page-todo .timeslot.alt .task {
      margin-left: 56%;
      -webkit-box-sizing: content-box;
      -moz-box-sizing: content-box;
      box-sizing: content-box
  }
 
  .page-todo .timeslot.alt .task .arrow {
      position: absolute;
      top: 6px;
      left: 0;
      height: 20px;
      width: 20px;
      border-left: none;
      border-right: 12px solid #63c2de;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent;
      margin-left: -18px
  }
 
  .page-todo .timeslot.alt .task .arrow:after {
      top: -12px;
      left: 3px;
      height: 20px;
      width: 20px;
      border-left: none;
      border-right: 12px solid #e1f3f9;
      border-top: 12px solid transparent;
      border-bottom: 12px solid transparent
  }
 
  .page-todo .timeslot.alt .time {
      top: 1px;
      left: auto;
      right: 50%;
      padding: 5px 40px 5px 10px
  }
 
  @media only screen and (min-width:992px) and (max-width:1199px) {
      .page-todo task .desc {
          display: inline-block;
          width: 70%;
          padding: 10px 10px;
          font-size: 12px
      }
      .page-todo task .desc .title {
          font-size: 16px;
          margin-bottom: 5px
      }
      .page-todo task .time {
          display: inline-block;
          float: right;
          width: 20%;
          padding: 10px 10px;
          font-size: 12px;
          text-align: right
      }
      .page-todo task .time .date {
          font-size: 16px;
          margin-bottom: 5px
      }
  }
 
  @media only screen and (min-width:768px) and (max-width:991px) {
      .page-todo .task {
          margin-bottom: 1px
      }
      .page-todo .task .desc {
          display: inline-block;
          width: 65%;
          padding: 10px 10px;
          font-size: 10px;
          margin-right: -20px
      }
      .page-todo .task .desc .title {
          font-size: 14px;
          margin-bottom: 5px
      }
      .page-todo .task .time {
          display: inline-block;
          float: right;
          width: 25%;
          padding: 10px 10px;
          font-size: 10px;
          text-align: right
      }
      .page-todo .task .time .date {
          font-size: 14px;
          margin-bottom: 5px
      }
      .page-todo .timeslot .task span {
          padding: 5px;
          display: block;
          font-size: 10px
      }
      .page-todo .timeslot .task span span {
          border: 0;
          background: 0 0;
          padding: 0
      }
      .page-todo .timeslot .task span span.details {
          font-size: 14px;
          margin-bottom: 0
      }
      .page-todo .timeslot .task span span.remaining {
          font-size: 12px
      }
  }
 
  @media only screen and (max-width:767px) {
      .page-todo .tasks {
          position: relative;
          margin: 0!important
      }
      .page-todo .graph {
          position: relative;
          margin: 0!important
      }
      .page-todo .task {
          margin-bottom: 1px
      }
      .page-todo .task .desc {
          display: inline-block;
          width: 65%;
          padding: 10px 10px;
          font-size: 10px;
          margin-right: -20px
      }
      .page-todo .task .desc .title {
          font-size: 14px;
          margin-bottom: 5px
      }
      .page-todo .task .time {
          display: inline-block;
          float: right;
          width: 25%;
          padding: 10px 10px;
          font-size: 10px;
          text-align: right
      }
      .page-todo .task .time .date {
          font-size: 14px;
          margin-bottom: 5px
      }
      .page-todo .timeslot .task span {
          padding: 5px;
          display: block;
          font-size: 10px
      }
      .page-todo .timeslot .task span span {
          border: 0;
          background: 0 0;
          padding: 0
      }
      .page-todo .timeslot .task span span.details {
          font-size: 14px;
          margin-bottom: 0
      }
      .page-todo .timeslot .task span span.remaining {
          font-size: 12px
      }
  }


          
What is Flux?

Flux is an architectural  design of Facebook application. It is certainly not MVC. 
Flux is essential to React because it helps to promote the use of React components in the way they are intended. 
Flux does this by creating a one-directional data flow. Data flows through three main portions of the Flux architecture: 

Dispatcher, 
Stores, 
and React views 

Target UI: