프로비저닝 Provisioning


프로비저닝의 의미는 특정 서비스를 제공받기 위하여 서비스 실행부터 시작해 서비스를 제공받기 전 단계까지 처리되는 일련의 절차를 말한다. 


사전적으로  '준비', '예비' 란 단어를 의미하는데, 소프트웨어 프로그램을 예를 들면, 프로그램이 초기화 되면서, 사용자에게 짠하고 나타나기 전까지 수행되는 준비 단계를 프로비저닝이라한다. 다시 말해 배포/빌드/업데이트 등 소프트웨어를 사용하기 위해 관리 하는 절차 라고 이해하면 될 것 같다.


다른 산업군에서는 각 사업자(개발자) 별로 프로비저닝 절차를 표준화해 호환성을 고려 하기도 했다. 아래는 IPTV의 구체적인 프로비저닝 예시이다. 다음과 같이 IPTV단말을 초기화하여 IPTV 서비스를 수신하기 위한 6단계 절차를 명시해 다른 사업자의 단말도 동일한 절차를 이용해 서비스를 사용할 수 있도록 지정해 놓았다.


1) 네트워크 접속 단계

2) IPTV 사업자 정보 획득

3) IPTV 단말인증

4) 펌웨어 업그레이드

5) 소프트웨어 다운로드

6) IPTV 서비스 사업자 별 프로비저닝


이런 걸 표준화해서 다른 단말의 호환성을 높이다니... 


그럼 특정 소프트웨어에서 프로비저닝을 구축해 놓은게 없을까? 구글 검색 신을 이용해 검색!! 


검색을 해보니 프로비저닝 관리자라든지, 클라우드와 관련된 프로비저닝 결과가 많이 나온다. 간략히 정리하자면, 클라우드 서비스를 제공하기 위해, 네트워크, 저장공간, 그리고 웹앱 서비스 등을 제공하는데, 서비스 제공하기 전에 준비하는 단계를 프로비저닝이라는 용어를 사용한다. 클라우드 서비스를 제공하기 위한 준비 단계를 자동화 해, 프로비저닝 관리자라는 소프트웨어로 소개되고 있다.


프로비저닝이라는 단어를 처음 접한건 Eclipse Equinox/P2 프로젝트를 통해서다. Eclipse 기반의 어플리케이션을 위한 프로비저닝 플랫폼이라는 설명이 있었는데, 프로비저닝이 무슨 일을 하는지 몰라서, 그냥 이건 내가 접할 내용이 아닌가 보다하고 지나쳤었다.  Eclipse 기반 어플리케이션을 개발하면서 여러번 부딪혔지만, 깊게 보질 않았다. 그런데 단어를 익히고, 다시 한번 훑어보니, P2라는 프로젝트는 Eclipse 기반의 어플리케이션을 개발할 때, 배포/배치/빌드/업데이트 등을 표준화한 플랫폼이었다. 이것을 이용해 Eclipse 제품을 배포하다니~~!!! 다시금 내 무식함을 반성하며, 다음에는 P2를 정리해야 겠다고 다짐하며 이 글을 마친다.

Posted by 빌리 :

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

** 본 요약은 한빛미디어 '하이버네이트 프로그래밍' 책을 기준으로 작성되어져 있다.

** 본 설명은 바로 따라하기 하기엔 어려움이 있다. 책을 보지 않은 사람에게는 간단히 어떤 기능을 제공하는지 이해하는데 목적을 둔다.

** 하이버네이트 3.2.5.ga 버전, Ant 빌드를 기본적으로 사용한다.


5장 다양한 연관

이번 장에서는 5개의 주제를 가지고 설명한다. 앞장에서 다룬 연관을 조금 더 세밀하게 설정하는 방법을 배운다. 간단히 요약하면 다음과 같다. 

  1) 연관의 초기화 형태 : 느슨한(Lazy), 열성적인(Eager) 

  2) 순서가 있는 컬렉션 사용하기

  3) 순서가 있는 컬렉션 설정 보강하기

  4) 순서있는 연관 컬랙션 삭제에 따른 자동처리

  5) 재귀 연관

  

연관의 초기화 형태 : 느슨한(Lazy), 열성적인(Eager) 


객체내에 다른 객체를 참조하는 값을 가질 수 있는데, 참조되는 객체를 처음 생성때부터 초기화 할것인지(eager), 아니면 사용되기 전까지 초기화를 미룰 것인지(lazy) 설정하는 방법을 설명한다.


하이버네이트3부터는 연관 객체에 대한 생성은 늦은 초기화가 기본적으로 사용된다. 즉, 실제로 데이터를 사용하기 전까지 데이터베이스에서 로드하지 않는다는 것이다. 그러나 주의할 것은 하이버네이트 세션을 닫게 되면 연관 객체의 늦은 초기화가 작동하지 않아 LazyInitializationException을 던진다. 즉, Lazy를 사용하려면 하이버네이트 세션을 닫으면 안된다는 것이다. 


그러면 기본적인 늦은 초기화를 사용하지 않으려면 어떻게 하는지 알아보면 다음 코드 처럼 작성하면 된다.


<set name="association_Obj" table="AAA_BBB" lazy="false">

  <key column="AAA_ID"/>

  <many-to-many class="com.billy.sample.BBB" column="BBB_ID"/>

</set>


위와 같이 lazy="false"를 추가해 빠른(eagerly) 초기화를 설정할 수 있다.


다양한 연관에서 위와 같이 늦은 초기화를 사용안하게 할 수 있지만 특정 클래스 참조의 대한 부분 모두를 빠른 초기화 설정을 하는 방법은 매핑문서의 class 태그에 lazy="false"를 직접 사용하면 된다.



순서가 있는 컬렉션 설정 방법


만약 다른 연관된 테이블 데이터에 순서가 있을때, 순서를 지정하기 위한 방법을 다룬다. 일단 List 컬랙션과 맵핑해야 하고, 리스트의 순서를 설정하는 list_index 태그를 추가해야 한다. 그리고 순서 조정 값을 갖는 컬럼을 데이터 베이스에 추가해야 한다. 코드를 보면 다음과 같다.


<list name="bbbList" table="AAA_BBB" lazy="false">

  <key column="AAA_ID"/>

  <list-index column="LIST_POS"/>

  <many-to-many class="com.billy.sample.BBB" column="BBB_ID"/>

</list>


하이버네이트에서는 LIST_POS를 관리하여 나중에 데이터베이스에서 꺼낸 리스트 내용으 우리가 저장한 컬럼과 동일한 순서로 나오게 된다. 


순서가 있는 컬렉션 설정 보강하기


* 데이터베이스 스키마에 테이블을 넣는 방법

1) 테이블의 컬럼에 자바 객체의 매핑 프로퍼티를 명시하는 것

2) 컬렉션(컬렉션의 값 또는 연관)을 정의하고, 그 컬렉션을 관리하는데 사용할 테이블과 컬럼을 지정하는 것


* 엔티티와 컴포넌트

- 엔티티 : 다른 객체에 대해 독립적으로 생성, 질의, 삭제될 수 있는 것

- 컴포넌트 : 다른 엔티티의 종속적인 부분으로서 데이터베이스에 저장되거나 데이터베이스에서 검색 될 수 있는 것


* 컴포넌트 맵핑

<list name="tracks" table="ALBUM_TRACK">

  <meata attribute="use-in-tostring">true</meta>

  <key column="ALBUM_ID"/>

  <index column="LIST_POS"/>

  <composite-element class="com.oreilly.hh.data.AlbumTrack">

    <many-to-one class="com.oreilly.hh.data.Track" name="track" cascade="all">

      <meta attribute="use-in-tostring">true</meta>

      <column name="TRACK_ID" />

    </many-to-one>

    <property name="disc" type="integer" />

    <property name="positionOnDisc" type="integer" />

  </composite-element>

</list>


위 컴포넌트 맵핑은 새로운 AlbumTrack라는 클래스를 소개한다. 3장에서 소개한 N:N 맵핑의 경우 조인 테이블을 사용한다고 했는데, 그 조인 테이블을 사용하는 클래스가 없다고 설명했다. 그런데 이와 같이 N:N 조인테이블에 부가정보를 추가해 새로운 관리 클래스를 생성할 수 있다. 이렇게 생성된 코드를 살펴보면 다음과 같다.


public class AlbumTrack  implements java.io.Serializable {

  private Track track;

  private Integer disc;

  private Integer positionOnDisc;


  public AlbumTrack() {

  }


  public AlbumTrack(Track track, Integer disc, Integer positionOnDisc) {

    this.track = track;

    this.disc = disc;

    this.positionOnDisc = positionOnDisc;

  }

 

  public Track getTrack() {

    return this.track;

  }

  

  public void setTrack(Track track) {

    this.track = track;

  }

  public Integer getDisc() {

    return this.disc;

  }

  

  public void setDisc(Integer disc) {

    this.disc = disc;

  }

  public Integer getPositionOnDisc() {

    return this.positionOnDisc;

  }

  

  public void setPositionOnDisc(Integer positionOnDisc) {

    this.positionOnDisc = positionOnDisc;

  }


  /**

   * toString

   * @return String

   */

  public String toString() {

 StringBuffer buffer = new StringBuffer();


    buffer.append(getClass().getName()).append("@").append(Integer.toHexString(hashCode())).append(" [");

    buffer.append("track").append("='").append(getTrack()).append("' ");

    buffer.append("]");

     

    return buffer.toString();

  }

}


위 코드는 id 프로퍼티가 빠져있다. 컴퍼넌트 클래스는 식별 필드나 특별한 인터페이스 구현이 필요 없다. 


순서있는 연관 컬랙션 삭제에 따른 자동처리


- 부모 객체와 자식 객체의 종속성 설정 : 하이버네이트에서는 "부모"객체가 실행되면 "자식" 혹은 "의존" 객체까지 전이되는 연산을 cascade 어트리뷰트로 처리할 수 있다. 이 기능은 모든 종류의 컬렉션과 연관에 적용된다. 

- 사용 방법 : 객체 맵핑 프로퍼티에 <cascade> 태그를 추가한다.

  -> cascade 값 : none, save-update, delete, all(save-update+delete)

  -> 전체 default cascade 변경 : <hibernate-mapping> 태그에 default-cascade 어트리뷰트 추가

  -> 부모가 삭제되면 자식도 동시에 삭제 가능하도록 설정 가능

  -> 중간에 order관련 값들을 자동으로 변경해줌

  

재귀 연관


객체나 테이블에서 자체적으로 연관을 맺을 수 있다. 트리같은 객체 구조를 생성할 수 있다는 것이다. 이는 단순하다. 

Artist 클래스 맵핑 문서야 다음과 같이 자기 자신을 참조하는 필드를 추가하면 된다. 


<many-to-one name="actualArtist" class="com.oreilly.hh.data.Artist">

 <meta attribute="use-in-tostring">true</meta>

</many-to-one>


  

  

  

Posted by 빌리 :