Tuesday, January 17, 2023

 

Writing a serverless method that uploads documents:

Description: One of the most common techniques for uploading documents involves a form submission from the FrontEnd application. The user points to a file at a location specified by a folder on her computer and the client-side script in the frontend reads the file as a stream. When the same file content needs to be made available to the middleware, HTTP based methods struggle with the right way to send the data.

The key to send the data is to specify it as a multipart/form-data. This is the most efficient content-type for sending binary data to the server. Multiparts means that data is sent to the server in separate parts. Each of the components may have a different content type, file name and data. The data are separated from each other by a boundary string. When a command line tool like curl sends this request , it does so as a multipart request with a specially formatted POST message body and a series of parts separated by MIME boundaries

For example,

POST /echo HTTP/1.1

Content-Type: multipart/form-data; boundary=---WD9543A

Content-Length: 100

---WD9543A

Content-Disposition: form-data; name=”user-name”

John

---WD9543A

Content-Disposition: form-data; name=”text-data”;

filename=”user.txt”

Content-Type: text/plain

[Text-Data]

---WD9543A

When the controller receives this request, it can refer directly to the parts as follows:

Request.body.name

And

Request.file

For example:

Const multer = require(‘multer’)

Const upload = multer({ dest: os.tmpdir()});

Router.post(‘/upload’, upload.single(file), function (req, res) {

const title = req.body.title;

const file = req.file;

console.log(title);

console.log(file);

res.sendStatus(200);

});

 

Monday, January 16, 2023

 

Public clouds provide an adoption framework for businesses that helps to create an overall cloud adoption plan that guides programs and teams in their digital transformation. The plan methodology provides templates to create backlogs and plans to build necessary skills across the teams. It helps rationalize the data estate, prioritize the technical efforts, and identify the data workloads. It’s important to adhere to a set of architectural principles which help guide development and optimization of the workloads. A well-architected framework stands on five pillars of architectural excellence which include:

-          Reliability

-          Security

-          Cost Optimization

-          Operational Excellence

-          Performance efficiency

The elements that support these pillars are a review, a cost and optimization advisor, documentation, patterns-support-and-service offers, reference architectures and design principles.

This guidance provides a summary of how these principles apply to the management of the data workloads.

Cost optimization is one of the primary benefits of using the right tool for the right solution. It helps to analyze the spend over time as well as the effects of scale out and scale up. An advisor can help improve reusability, on-demand scaling, reduced data duplication, among many others.

Performance is usually based on external factors and is very close to customer satisfaction. Continuous telemetry and reactiveness are essential to tuned up performance. The shared environment controls for management and monitoring create alerts, dashboards, and notifications specific to the performance of the workload. Performance considerations include storage and compute abstractions, dynamic scaling, partitioning, storage pruning, enhanced drivers, and multilayer cache.

Operational excellence comes with security and reliability. Security and data management must be built right into the system at layers for every application and workload. The data management and analytics scenario focus on establishing a foundation for security. Although workload specific solutions might be required, the foundation for security is built with the Azure landing zones and managed independently from the workload. Confidentiality and integrity of data including privilege management, data privacy and appropriate controls must be ensured. Network isolation and end-to-end encryption must be implemented. SSO, MFA, conditional access and managed service identities are involved to secure authentication. Separation of concerns between azure control plane and data plane as well as RBAC access control must be used.

The key considerations for reliability are how to detect change and how quickly the operations can be resumed. The existing environment should also include auditing, monitoring, alerting and a notification framework.

In addition to all the above, some consideration may be given to improving individual service level agreements, redundancy of workload specific architecture, and processes for monitoring and notification beyond what is provided by the cloud operations teams.

Sunday, January 15, 2023

#codingexercise 

Merge K sorted Lists:

List<Integer> merge(List<List<Integer>> slices)

{

var result = new List<Integer> ();

while(slices.size() > 0) {            

              slices.sort(new ListComparator<List<Integer>>());

              while(slices.size() > 0 && slices[0].size() == 0) {

                        slices.remove(0);

              }

               If (slices.size() == 0) {

         return result;

}              

result.add(slices[0].removeAt(0));

}

return result.toList():

}

 

public class ListComparator<List<Integer>> implements Comparator<List<Integer>> {

        public int compare(List<Integer> l1, List<Integer> l2) {

                           if (l1 == null && l2 == null) return -1;

                           if (l1 == null) return -1;                        

                           if (l2 == null) return 1;

                           if (l1.size() == 0 && l2.size() == 0) return -1;

                           if (l1.size() == 0) return -1;

                           if (l2.size() == 0) return 1;

                          return l1.get(0).compareTo(l2.get(0));

        }

}

 

Test cases:

1.       Null, Null -> []

2.       Null, [] -> []

3.       [], Null -> []

4.       [],[] -> []

5.       [1],[] -> [1]

6.       [], [1] -> [1]

7.       [1],[1] -> [1, 1]

8.       [1],[2] -> [1, 2]

9.       [2],[1] -> [1,2]

10.   [1],[2,3] -> [1,2,3]

11.   [1,2],[3] -> [1,2,3]

12.   [1,2,3],[] -> [1,2,3]

13.   [1,3][2] -> [1,2,3]

14.   [],[1,2,3] -> [1,2,3]

15.   [1][2][3]->[1,2,3]

16.   [1][2],[3],[5][6]-> [1,2,3,5,6]

17.   [][][1,2,3]->[1,2,3]

18.   [][1,2,3][]->[1,2,3]

19.   [1,2][3,5,6][]->[1,2,3,5,6]

20.   [1,2][3][4,5][6]->[1,2,3,4,5,6]

21.   [1,2,3,4,5,6,7][]->[1,2,3,4,5,6,7]

Reference: previous post

Saturday, January 14, 2023

#codingexercise

Merge two sorted lists: 

List<int> merge(List<int> A, List<int> B) 

{ 

List<int> result = new ArrayList<int>(); 

While (A != null && B != null && A.size() > 0 && B.size() > 0) 

{ 

 int min = A.get(0) <= B.get(0) ? A.remove(0) : B.remove(0); 

 result.add(min); 

} 

While (A != null && A.size() > 0) 

{ 

result.add(A.remove(0)); 

} 

While(B != null && B.size() > 0) 

{ 

result.add(B.remove(0)); 

} 

return result; 

} 

 

Test cases: 

  1. Null, Null -> [] 

  1. Null, [] -> [] 

  1. [], Null -> [] 

  1. [],[] -> [] 

  1. [1],[] -> [1] 

  1. [], [1] -> [1] 

  1. [1],[1] -> [1, 1] 

  1. [1],[2] -> [1, 2] 

  1. [2],[1] -> [1,2] 

  1. [1],[2,3] -> [1,2,3] 

  1. [1,2],[3] -> [1,2,3] 

  1. [1,2,3],[] -> [1,2,3] 

  1. [1,3][2] -> [1,2,3] 

  1. [],[1,2,3] -> [1,2,3]