본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


AsterixDB

AsterixDB 테스트용 환경 구축 - 3 (with Java, Java연동)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2019. 11. 4.

 

 

아스트릭스DB는 기본적인 웹 콘솔인 19001번 포트를 활용해서 웹 GUI환경을 지원한다.

웹 콘솔, 여러 쿼리를 손쉽게 HTTP로 전송해서 결과를 받아볼 수 있다.

 

 

또한 19002라는 포트를 사용해서 다른 개발언어에서 연동을 하기위한 TCP/IP 통신을 지원하는데, 마찬가지로 HTTP프로토콜을 활용한 기능을 지원하여 준다.

아스트릭스db를 실행하면 볼 수 있는 실행중인 대표적인 포트 2개

 

 

예전 오라클, Mysql, MSSQL 및 몽고DB등 여러 데이터베이스는 특정 모듈이나 라이브러리를 설치해서 다른 언어에서 연동을 하는 방식이였다면, 아스트릭스DB는 자체적으로 RestAPI형식의 HTTP서버를 지원함으로써 전송하는 규칙만 잘 활용한다면 손쉽게 내용을 전달하고 주고받을 수 있다.

조금 웃긴건 아스트릭스DB와 관련된 공식 사이트를 들어가보면 get방식으로 요청하는 방법이 있는데..해당 방식은 버전이 올라가면서 더 이상 지원하지 않고 post 방식만 지원한다는 점 이다.

https://ci.apache.org/projects/asterixdb/api.html

 

 

일단 백그라운드 언어를 사용해서 제대로 주고받을 수 있는지 테스트하기 위해서 Java를 활용하여 간단한 요청기능을 만들어 보았다.

사용 라이브러리는 자바의 기본 라이브러리를 대부분 사용 하였다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;

public class SimpleAast {

	public static final String SERVER_ADDRESS = "http://서버주소:19002/query/service";
	
	
	public static void main(String[] args) {
          Map<String,Object> params = new LinkedHashMap<>(); // 파라미터 세팅
          params.put("쿼리를위한 키 값", "사용할 쿼리");
		
          List<Object> result = queryToServer(SERVER_ADDRESS, params);
          result.forEach(System.out::println);

	}

	
	private static List<Object> queryToServer(String serverUrl, Map<String,Object> params){
		List<Object> list = null;
		HttpURLConnection conn = null;
		InputStreamReader ins = null; 
		BufferedReader in = null;
		try {
			URL url = new URL(serverUrl); // 호출할 url
			
	        StringBuilder postData = new StringBuilder();  //post파라미터 넣기
	        for(Map.Entry<String,Object> param : params.entrySet()) {
	            if(postData.length() != 0) postData.append('&');
	            postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
	            postData.append('=');
	            postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
	        }
	        byte[] postDataBytes = postData.toString().getBytes("UTF-8");
	 
	        conn = (HttpURLConnection)url.openConnection();
	        conn.setRequestMethod("POST");
	        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
	        conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
	        conn.setDoOutput(true);
	        conn.getOutputStream().write(postDataBytes); // POST 호출
	 
	        ins = new InputStreamReader(conn.getInputStream(), "UTF-8");
	        in = new BufferedReader(ins);
	 
	        String inputLine;
	        String result = "";
	        while((inputLine = in.readLine()) != null) { // response 결과 조립
	        	result += inputLine;
	        }
	        
	        result = "[" + result + "]";
			JSONArray array = new JSONArray(result);
			list = array.toList();	        
	        
		} catch (Exception e) {
			e.printStackTrace();
			HashMap<Object, Object> errors = new HashMap<>();
			errors.put("result", "FAIL");
			errors.put("why", e.getMessage());
			list.add(errors);
		} finally{
			try { ins.close(); } catch (IOException e) { e.printStackTrace(); }
	        try { in.close(); } catch (IOException e) { e.printStackTrace(); }
	        conn.disconnect();
	        try {
				Thread.sleep(5000);  //아스트릭스디비의 커넥션이 올바르게 종료되려면 5초(?)를 기다려주어야 한다.
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	

}

 

기본 패키지를 사용하였고, json형식으로 결과를 되돌려주는 아스트릭스db를 위해서 org.json이라는 라이브러리를 1개 사용하였다.

maven을 활용해서 설치하였으며, json파싱과 관련된 다른 라이브러리를 사용해도 무방하다.

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180130</version>
</dependency>					

 

여기서 서버로 질의하기위한 파라미터의 키 값은 statement를 사용 하여하 하며, value값은 일반 질의문을 사용하면 된다.

Map<String,Object> params = new LinkedHashMap<>(); // 파라미터 세팅
params.put("statement", "USE TEST_DB;SELECT * FROM MY_FORM_SET;");  //이런식으로

 

실제 구동후에 출력을 해 보았다.

오..뭔가 나온다.

 

results부분이 내가 원하는 값 이며, 해당 값은 Json형식으로 되어있다.

지금 사용한 라이브러리는 해당 results값을 HashMap으로 매핑하여준다.

 

 

재미있는 점은 http통신을 한 뒤에 아스트릭스db의 올바른 응답종료를 위해서 5초간 기달려 주어야 한 다는 점이다.

소스코드를 보면, 하단부에 Thread.sleep(5000); 이라는 부분이 있다.

해당부분을 제거하고 질의문을 전달하면 결과는 정상적으로 받아지는데, 서버에서는 아래 사진처럼 오류가 난다.

아스트릭스db에 있는 cc.log에 나온 모습. 커넥션이 정상적으로 종료되려면 최소 5초는 기달려줘야 한다...

 

TYPE을 만들거나, DATASET을 만드는 경우에는 status 값으로 성공여부를 알려주며 성공하면 success값을 되돌려 준다.

 

 

데이터를 저장하거나 수정하는 경우에 key 값에도 반.드.시 쌍 따옴표를 붙여야하며, 만약 붙이지 않는다면 해당 필드는 dataset으로 간주되어버린다.

즉, 무조건 질의문을 작성할 때 키와 값은 반드시 쌍따옴표를 붙여야 한다. 숫자면 상관없지만..

키 값에 쌍따옴표를 붙이지 않고 등록을 요청하는 모습, 또한 날짜값에 datetime인데 date형식으로 저장하려는 모습.
서버 로그에 찍힌 모습, text필드를 dataset으로 인식하여 버린다.

 

해당 오류를 해결하려면 반드시 키 값에도 쌍따옴표를 붙여야한다.

데이터의 형식에 맞는 값을 전달하는 것도 잊지말아야 한다. (숫자면 숫자, 문자면 문자, 날짜면 날짜 등등..)

저렇게 쌍따옴표를 전부 키 값에도 붙여주면 정상적으로 동작한다.

 

 

과연 아스트릭스DB에서는 그룹핑, 페이징, LIMIT 및 기타 질의문에 대해서 얼마나 잘 동작하는걸까?

해당 기능에 대해서 좀 더 살펴보아야 하겠다.

 

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글