Sunday, October 2, 2022

NodeJs Read XML file and Parse Data

Hello,

Few days back I worked on task to read XML file in NodeJs and parse the data and convert data to the JSON format. Here in this blog I am going explain how I did achieved this. 

Following is our sample XML file.

<root>

    <parent>

        <firstchild>First Child Content 1</firstchild>

        <secondchild>Second Child Content 1</secondchild>

    </parent>

    <parent>

        <firstchild>First Child Content 2</firstchild>

        <secondchild>Second Child Content 2</secondchild>

    </parent>

</root>

Step 1 : Install necessary NPM packages

First install following packages in your NodeJs application.

npm install --save xmldom

mpm install --save hashmap

Here xmldom is the package we are going to use to parse the XML data and hasmap package we are going to use to convert and save data in JSON format.

Step 2 : Import necessary packages in script

const { readFile } = require('fs/promises');

const xmldom = require('xmldom');

const HashMap = require('hashmap');

We are going to use readFile from fs/promises. Also we will use xmldom to parse the string data. xmldom is a A JavaScript implementation of W3C DOM for Node.js, Rhino and the browser. Fully compatible with W3C DOM level2; and some compatible with level3. Supports DOMParser and XMLSerializer interface such as in browser.

Step 3 : Read the XML file

const readXMLFile = async()=> {

var parser = new xmldom.DOMParser();

        const result = await readFile('./data.xml',"utf8");

        const dom = parser.parseFromString(result, 'text/xml');

}

Here we are using async function to read the XML file as we want to wait till XML file is completely finished. Also we created a xmldom.DOMParser which we will use to parse the string data of the file. This parser will give you all the TAGs of the XML file just like we access standard HTML tags. With this we can use getElementsByTagName to get XML tags.  

Step 4 : Convert XML data to hasmap

const readXMLFile = async()=> {

var parser = new xmldom.DOMParser();

        const dataMap = new HashMap();

        const result = await readFile('./data.xml',"utf8");

        const dom = parser.parseFromString(result, 'text/xml');

        var parentList = dom.getElementsByTagName("parent");

        for(var i =0; i < parentList.length; i++) {

        const parent = parentList[i];

            const firstchild = parent.getElementsByTagName("firstchild")[0].textContent;

        const secondchild = parent.getElementsByTagName("secondchild")[0].textContent;

            const parentMap = new HashMap();

        parentMap.set("firstchild", firstchild);

        parentMap.set("secondchild", secondchild);

            dataMap.set(i, parentMap);

        }

}


In the above function we got list of parents by getElementsByTagName method and then we are iterating  through it and accessing the child tags and getting it's text content. Then we are simply storing it in hasmap with unique key. 

Hope this helps you.

Sunday, July 3, 2022

Mock node-fetch with JEST

Recently I tried my hands on Jest - the popular JavaScript Testing Library. In my application we were using node-fetch to make API calls. I used Jest to mock and test this API calls. Here in this blog I will explain on how to mock node-fetch with Jest. 

Following is my function to call the GET API. 

fetch_get.js

const fetch = require('node-fetch');

module.exports = async () => {

    return await fetch('http://YOUR_GET_URL').then(res => res.json());

};

Now to test this create a test file with name test.fetch_get.js

Step 1: First import the function.

const fetch_get = require('../fetch_get');


Step 2 : Mock the node-fetch with Jest

const fetch = require('node-fetch');
jest.mock('node-fetch', ()=>jest.fn())

Step 3: Create Mock response

const mockedRes = {
  "success": true,
  "data": [
    {
        id: 1,
        text: 'Test Data 1'
    },
    {
        id: 1,
        text: 'Test Data 2'
    }
  ]
};

Step 4: Add Test 

describe("Test get fetch", () => {
    let data;
    it('It should return the data', () => {
      const response = Promise.resolve({
            ok: true,
            status: 200,
            json: () => {
                return mockedRes;
            },
        });
        fetch.mockImplementation(()=> response)
        data = await fetch_get();
        expect(data).toEqual(mockedRes);
    });
});

In above code we have created a rest and mocked the response to return our response when we call .json() method for response. Then we are simply comparing the response. This is a very simple test. Here in stead of comparing data, you may have other tests like checking length of data or checking specific data etc.

Step 5: Run Test

Run the test with npm test or npm run test and you will see the following result.

Test get fetch
    ✓ It should return the data (17 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.313 s, estimated 1 s

Hope this helps you.

Saturday, January 29, 2022

How to Execute Shell Script from Dockerfile

Recently I faced a problem with Docker build. Before we build the image there was a requirement to cleanup something from MongoDB. For that we tried to create shell script and execute it from Dockerfile before we start the service. Here in this blog I will explain how you can execute the shell script from Dockerfile. 

For that first create the shell script in the same context of Dockerfile. That means the file should be in the same folder or subfolder where Dockerfile is there. 

We can not access file outside the Docker build context so file has to be in the same folder.

nano test.sh


You can put your content in this file for the tasks you want to do with this file. 


Now first we will copy the file in docker build context. So that it can be executed. This step is mandatory or else it will not find file. Add following lines of code in your Dockerfile.


FROM alpine3.15

COPY test.sh ./test.sh


Next step we have to change access rights of the script so it can be executed.


RUN chmod +x ./test.sh


Now since we have file in the Docker build context and it has proper access rights we can execute the file. 


RUN sh ./test.sh


That's it and now when to service starts it will execute the file and do all the actions which you have added in shell script.


Hope this helps you. 

Monday, January 3, 2022

Kubernetes ImagePullBackOff error

Recently I faced an issue while working Kubernetes cluster. I was trying to build docker image from local repository to test some changes in production before we merge the code. After building the docker image and recreating the container it was showing ImagePullBackOff error when I check the status with 

kubectl get pods

In this blog I am going to mention the possible cause for this error and will explain the resolution which worked for me.

In a Kubernetes, there’s an agent on for node which is called kubelet. This is responsible for running containers in the nodes. For some reason if image can't be pulled the kublet will throw ImagePullBackOff error. 

There are some possible reasons for this when kubectl is not able to pull image from mentioned registry. 

Either image or tag is not available. 

The name of the image or tag is wrong in deployment yaml file

kubectl does not have access to image registry. 

In my case there was no such issues mentioned above. The image with tag was there. I have specified the correct name in deployment yaml file and because it was a local registry, there was no need of authentication. 

So here is how I solved this issue. I set image pull policy to following value in my deployment yaml file.

imagePullPolicy: IfNotPresent

The reason it worked is, the kubectl was trying to find image in registry but it was not present because it was local registry so then it tried to find image in local repository and caches it. 

This solution worked for me because I was using local registry. If you are facing such issue try setting above value to imagePullPolicy and it may work. Hope this helps you.