체인의정석

node.js에서 API로 파일 다운 및 압축 파일 다운 받게 만들기 (블록체인 프로젝트 DB정합성 검사기 제작) 본문

개발/backend

node.js에서 API로 파일 다운 및 압축 파일 다운 받게 만들기 (블록체인 프로젝트 DB정합성 검사기 제작)

체인의정석 2023. 5. 17. 15:31
728x90
반응형

사용한 상황

DB 정합성 체크를 받아야하는 상황 + 보안 문제로 DB에 접근이 어려운 상황에 따라서 필요한 부분만 DB에서 뽑아내서 받아오는 관리자 API를 만들어야 하는 상황이다.

여러 서버에 접근해서 DB값을 뽑아와야 하는 상황. 또한 테이블과 데이터베이스가 꾸준히 변동되는 구조이다.

그러나 sequalize를 사용중이므로 자동적으로 db에 대한 정보가 경로상의 폴더와 파일명으로 업데이트 되기 때문에 따라서 먼저 각 DB별로 db정보를 읽어와 파일을 생성해주는 api, path를 가져오는 함수를 만들어 두었으며, 이를 통해  특정 블록번호 기준으로 데이터를 조회하는 기능과 내부적으로 파일을 생성한 후 해당 파일 하나 또는 전체 데이터에 대해서 파일로 가져오는 부분을 구현하였다.

이러한 기능들을 이용하면 서비스 외부에 db audit 서비스를 하나 더 생성하여서 각 환경별 호출 뿐 만 아니라 다양한 데이터 정합성 체크가 가능하다.

일반적으로는 db 내용자체에 대한 정합성을 거칠 필요가 없지만 내가 다루는 데이터는 블록체인 데이터이기에 분산장부 상의 데이터와의 교차 검증이 필요하며 어차피 분산장부에 다 노출되어 있는 정보이기 때문에 보안적인 이슈도 적어 일반적으로 하지 않는 특이한 상황의 작업이라고 할 수 있다.

사용한 모듈 - adm-zip

https://npm.io/package/adm-zip

 

npm.io | NPM packages search engine

npm.io is an NPM packages aggregator and search engine designed to make your node package search fast, smooth and simple.

npm.io

node.js 의 모듈이며 압축 파일을 만드는것 외에도 쓸 수도 있다고 한다.

위의 공식문서 예제 중


	var AdmZip = require('adm-zip');

	// reading archives
	var zip = new AdmZip("./my_file.zip");
	var zipEntries = zip.getEntries(); // an array of ZipEntry records

	zipEntries.forEach(function(zipEntry) {
	    console.log(zipEntry.toString()); // outputs zip entries information
		if (zipEntry.entryName == "my_file.txt") {
		     console.log(zipEntry.data.toString('utf8')); 
		}
	});
	// outputs the content of some_folder/my_file.txt
	console.log(zip.readAsText("some_folder/my_file.txt")); 
	// extracts the specified file to the specified location
	zip.extractEntryTo(/*entry name*/"some_folder/my_file.txt", /*target path*/"/home/me/tempfolder", /*overwrite*/true)
	// extracts everything
	zip.extractAllTo(/*target path*/"/home/me/zipcontent/", /*overwrite*/true);
	
	
	// creating archives
	var zip = new AdmZip();
	
	// add file directly
	zip.addFile("test.txt", new Buffer("inner content of the file"), "entry comment goes here");
	// add local file
	zip.addLocalFile("/home/me/some_picture.png");
	// get everything as a buffer
	var willSendthis = zip.toBuffer();
	// or write everything to disk
	zip.writeZip(/*target file name*/"/home/me/files.zip");

admZip을 써서 addLocalFile을 사용하면 압축파일이 되는것을 확인하고 각 파일을 순회하며 읽어와서 압축파일을 만들었으나 보기에는 어렵게 결과가 나왔다. 이에 대해 구글링을 하던 중 새로운 함수를 발견했다. (공식문서 업데이트가 안되어 있는것 같다.)

 

https://stackoverflow.com/questions/37097658/adm-zip-files-zipped-as-folder

 

Adm Zip - files zipped as folder

I am using adm-zip to zip the local directory and all its nested files and directories. var AdmZip = require('adm-zip'); var pathToZip = process.env.PUBLIC + '/Demo/Backup.zip'; var zip = new AdmZ...

stackoverflow.com

바로 아래 부분

var AdmZip = require('adm-zip');
var pathToZip = process.env.PUBLIC + '/Demo/Backup.zip';
var zip = new AdmZip();
zip.addLocalFolder("C:\\Users\\Public\\Test\\db");
zip.writeZip(pathToZip);

이렇게 하고 만들어 본 결과 api를 통해 호출하게 되면 폴더 구조 그대로 다운이 되는 것을 확인하였다.

            for(let 특정DB of 전체DB리스트) {
                for(let 테이블 of 전체테이블리스트) {
                    const exact_path = this.getFilePath(특정DB,특정테이블);
                    zip.addLocalFile(exact_path);
                }
            }

따라서 위와 같이 해도 되지만

            zip.addLocalFolder(`${__dirname}/../output`)
            const zipPath = `${__dirname}/../output/zipAll.zip`;
            zip.writeZip(zipPath)

그냥 폴더 경로 자체를 넣으니까 잘 된다.

res.download

이렇게 파일을 만든 후에 다운로드를 또 하고 싶다면?

zip이 있는 파일 경로를 호출해 주는 함수를 만든 후에 이를 router에서 호출해서 응답할 때 

res.download로 보내주면 된다.

router.get("/downloadZip", function(req,res) {
    const path = 클래스이름.downloadZip();
    res.download(path);
});

확장

같은 방식으로 req에 조회하고자 하는 블록번호 및 데이터베이스와 테이블 이름등을 넘겨 받고 이를 통해 경로를 각 상황에 맞게 사용해주었더니 여러 환경의 데이터베이스에서 직접 audit에 필요한 값들을 넣을 수 있었다.

받는 값들은 블록체인상에 기록된 값들 중에서도 정보 자체가 없고 누락여부만 체크가능한 유니크값인 txhash나 블록번호 또는 이벤트 아이디 정도로 잡아서 자동화 시켜두었다.

728x90
반응형
Comments