달력

102025  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

본 특집은 최근 들어 국내 IT 업계의 주요 화두가 되고 있는 서비스 지향 아키텍처(Service Oriented Architecture, 이하 SOA)를 주제로, 외국 developerWorks 사이트에 게재된 글 중 국내 개발자에게 도움이 될만한 글들을 모아 소개하고 있다.

각각의 기술문서에 대한 소개에 앞서, 잠시 SOA 가 대두된 배경을 살펴보자. (참고자료: SOA 입문)

"더이상 IT 환경은 비즈니스 환경과 무관하게 계획되고, 구축되며, 운영될 수 없다!" 기업 환경이 빠르게 변화함에 따라, 기업 내 IT 환경은 기업의 생존을 위한 기본 인프라로서, 기업의 흥망성쇠에 중요한 역할을 한다. 예전의 IT 환경은 장차의 변화를 예측하고, 이에 대한 체계적인 분석을 통해 예상된 변화에 대응할 수 있도록 설계되어 구축되곤 했다. 그러나, 이러한 과정은 여러 시행착오를 거치며 실제 운용에 이르기까지 설계와 구축에 상당한 기간이 소요되었다. 또한 변화된 요구에 대해서는 능동적으로 대처하기 어려운 한계가 있다.

그러나, 최근의 비즈니스 환경은 외부의 변화 및 내부의 요구사항에 대한 보다 빠른 대응을 필요로 하고 있다. 이는 기업의 성공적인 운영을 위해 예측되어진 변화외에 예측하지 못했던 변화에 대해서도 발빠르게 대응할 수 있는 능력이 강하게 요구되고 있으며, 기업의 인프라로서 IT 환경 또한 기업의 판단에 따른 비즈니스 변화에 대해 발빠르게 대처할 수 있도록 요청되고 있다. 그러나 기존의 방식으로 비즈니스 환경의 변화요구에 맞게 IT 환경을 재구성하기에는 너무 많은 시간과 비용이 소요된다. 따라서, 기존의 IT 패러다임으로는 이러한 변화에 제대로 대응할 수 없으며, 이로 인해 다른 기업과의 경쟁에서 뒤처지는 경우를 어렵지 않게 볼 수 있다. 이에 따라 IT 환경에 대한 새로운 패러다임이 강하게 요구되었으며, 이에 SOA 가 제시되었다.

SOA 의 가장 큰 특징은 바로 반복사용이 가능한 서비스이다. 웹서비스에 근간하여 기업내의 각 업무단위를 독립적이고 반복사용이 가능한 형태인 서비스라는 컴포넌트로 구현하여, ESB(Enterprise Service Bus)를 통해 이를 유연하게 연결함으로써 결과물을 산출한다. 웹서비스의 유연한 연결방식을 바탕으로, 각각의 서비스는 필요에 따라 새로운 형태로 연결되어 구성이 될 수 있으며, 이러한 변경을 통해 비즈니스 환경이나 요구사항의 변화에 발빠르게 대처할 수 있는 것이다. 즉, SOA 는 내부의 단위 업무를 서비스로 정의하고 이를 조합하여 ESB로 연결함으로써 하나의 애플리케이션을 구성한다. (이를 컴포지트 애플리케이션 이라고 한다.) 이렇게 구성된 애플리케이션은 기존 애플리케이션과는 달리 이미 정의된 서비스들을 조합하여 필요한 기능을 구현하며, 새로운 기능의 추가나 개선은 개발된 서비스중 일부를 변경하거나 재조합함으로써 구현할 수 있다.
바로 이러한 SOA 를 통해 기업은 비로소 외부의 변화에 빠르게 대응할 수 있으며, 내부의 새로운 요구사항을 적극적으로 수용할 수 있게 되는 것이다.

우선, 아래의 시리즈는 일반론적인 관점에서 SOA에 대한 고찰과 접근방식을 설명하고 있다. 첫번째 글에서 기업에서 SOA 를 적용하고 할 때의 다양한 구축 패턴을 비교하여 각각의 장점에 대해 살펴보며, 이를 기반으로 두번째 글에서 분석 및 설계과정을 통해 서비스를 구성하는 방법에 대해 살펴보고 있다.


좀더 체계적인 구축방법론은 아래의 기사들을 통해 살펴볼 수 있다. 아래의 기사들에서 저자는 SOA 를 구축하는 새로운 프로세스와 방법론을 설명하고, 성숙도 모델을 제시하여 각 기업의 성숙도 레벨을 평가하는 방법에 대해 설명하고 있다.


본격적인 SOA 프로그래밍 모델에 대한 설명은 아래 9편의 시리즈 글를 통해 살펴볼 수 있다. 이 시리즈를 통해 여러가지 새로운 SOA 관련 프로그래밍 모델을 살펴볼 수 있으며, 기업내에서 SOA를 어떻게 구축하여 활용할 수 있는지에 대해 설명하고 있다.


지금까지 조금은 지루한 내용었다면, 잠깐 쉬어가는 의미에서 관련 전문가 인터뷰를 살펴보자. 다음 글은 IBM에서 근무하는 기술전문가와의 인터뷰를 통해 SOA 에 대한 실질적인 이해의 면모를 잠깐이나마 살펴볼 수 있으며, IBM의 차세대 사용자 인터페이스의 추축이 되는 IBM WebSphere Portal 및 Workplace 를 통한 SOA 구축에 대해 알아볼 수 있다.


마지막으로 SOA 의 반패턴 연구를 통해, 일반적인 상황에서 발생하기 쉬운 오류들을 분석하여 이미 경험된 실수를 반복하지 않고 이를 피할 수 있는 방법을 살펴본다.


이상에서 developerWorks 에서 게시된 글을 통해 서비스 지향 아키텍처(SOA) 전반에 대해 살펴보았다. 위의 글을 읽으면서 일부 독자들은 여전히 부족한 무엇인가를 느꼈으리라 생각된다. 그 이유중의 하나는 서비스 지향 아키텍처는 여전히 성장하고 있으며, 계속해서 보완되고 있다는 점도 빠질 수 없을 것이다. 이러한 부족함을 메워나가기 위해 한국 developerWorks 는 웹사이트내 "SOA와 웹서비스" 영역을 통해, 이후에도 더 많은 서비스 지향 아키텍처(SOA)와 관련된 문서들을 국내 개발자들에게 제공할 것이다. 독자 여러분의 많은 성원을 기대한다.

'java' 카테고리의 다른 글

java의 excel 컨트롤 - jxl, poi  (0) 2008.09.16
jxl 을 이용하여 images 가져오기  (0) 2008.09.16
SOA와 웹서비스 입문 (한글) - IBM developerworks  (0) 2008.09.10
Junit의 TestSuite  (0) 2008.09.02
Connection Pool - DBCP  (0) 2008.09.01
Posted by marryjane
|

developerWorks 웹 서비스 존에는 수 백 개의 기술자료, 튜토리얼, 팁이 포함되어 있으며, 개발자들이 웹 서비스 관련 애플리케이션을 만드는데 일조하고 있습니다. 하지만 이 새로운 주제를 시작하는 사용자들에게는 오히려 이 많은 정보들이 부담스러울 수 있습니다. 이 페이지는 웹 서비스를 시작할 방법을 모색하는 개발자들을 위한 장소입니다. 기본적인 웹 서비스 기술이 포함되어 있으며, developerWorks의 관련 기술자료, 튜토리얼과 팁, IBM 교육 서비스, 웹 캐스트, 워크샵, IBM 제품들로 연결됩니다.
  서비스 지향 아키텍쳐(SOA)

Service-Oriented Architecture(SOA(서비스 지향 아키텍쳐))는 정의가 잘된 인터페이스와 서비스들 간 콘트랙트(contracts)를 통해, 서비스라고 하는 애플리케이션의 다양한 기능 단위를 상호 연관시키는 컴포넌트 모델입니다. 인터페이스는 하드웨어 플랫폼, 운영 체계, 프로그래밍 언어에 독립적인 방식으로 정의됩니다. 따라서 다양한 시스템들에 구현된 어떤 서비스라도 일반적이고 통합된 방식으로 인터랙팅 할 수 있습니다.

특정 구현에 얽매이지 않은 중립적인 인터페이스를 가졌기 때문에 서비스들간 약결합(loose coupling)으로 알려져 있다. 약결합 시스템의 장점은 기민성과 각 서비스의 내부 구조 및 구현의 변화에 대응할 수 있는 능력을 꼽을 수 있습니다. 반면 강결합(tight-coupling)은 애플리케이션의 다양한 컴포넌트들이 기능과 형식면에서 밀접하게 연관되어 있어 애플리케이션 일부나 전체를 변경할 때 까다롭습니다.

약결합 시스템의 필요성은 비즈니스 애플리케이션이 변화하는 환경에 빠르게 적응해야 하는 데서 기인했습니다. 정책, 주력 비즈니스, 비즈니스 포커스, 파트너쉽, 산업 표준, 비즈니스의 본질에 영향을 미치는 관련 요소들은 늘 변화하기 마련입니다. 우리는 이러한 환경에 유연하게 대처할 수 있는 비즈니스를 온 디맨드 비즈니스(On demand business)로 명명하고 있습니다.

서비스 지향 아키텍쳐는 새로운 것은 아니고, 다만 지난 십년 동안 출현했던 강결합 객체 지향 모델에 대한 대안 모델이라 할 수 있습니다. SOA 기반 시스템이 개별 서비스가 객체 지향 디자인으로 구현될 수도 있다는 것을 배제하지 않는 반면, 전체 디자인은 서비스 지향입니다. 시스템 내에 객체를 허용하기 때문에 SOA는 객체 기반 이지만 전체가 객체 지향은 아닙니다. 그 차이는 인터페이스에 있습니다. 초기 SOA 시스템의 고전적인 예는 Common Object Request Broker Architecture (CORBA)인데 이는 SOA와 비슷한 개념을 정의하고 있습니다.

하지만, 오늘날 SOA는 eXtensible Markup Language (XML)에 기반하여 진보했다는 점에서 차별됩니다. Web Services Definition Language (WSDL)라고 하는 XML 기반 언어로 된 인터페이스를 설명하게 되면서, 서비스는 CORBA의 Interface Definition Language (IDL)보다 동적이고 유연한 인터페이스 시스템으로 옮겨가게 되었습니다.

웹 서비스가 SOA를 구현할 수 있는 유일한 방법은 아닙니다. 앞서 설명했던 CORBA도 하나의 방법이고, 따라서 IBM의 MQseries 같은 메시지 지향 미들웨어도 마찬가지 입니다. 하지만 아키텍쳐 모델이 되기 위해서는 서비스 디스크립션 그 이상이 필요합니다. 전체 애플리케이션이 서비스들 간 워크플로우를 어떻게 수행하는지에 대한 정의를 내려야 합니다. 뿐만 아니라 비즈니스 연산 대 비즈니스에서 사용되는 소프트웨어 연산 사이의 변형 포인트를 찾아야 합니다. 따라서 SOA는 비즈니스의 상용 프로세스를 기술 프로세스와 연관시킬 수 있어야 하고, 둘 사이에서 워크플로우 관계를 매핑해야 합니다. 예를 들어, 공급자 역할을 하는 것은 비즈니스 프로세스이고 새롭게 공급된 것을 추가하여 부품 데이터베이스를 업데이트 하는 것은 기술 프로세스이다. 따라서 워크플로우는 SOA 디자인에서 중요한 역할을 합니다.

더욱이, 동적 비즈니스의 워크플로우에는 부서들 간 작동 뿐만 아니라, 다른 외부 파트너들의 작동이 포함되어 있어 여러분에게는 제어권이 없습니다. 서비스 레벨 계약과 운영 정책의 형태로, 서비스들 간 관계가 발생하는 방법에 대한 정책을 정의해야 합니다.

마지막으로, 계약 조건에 따라 프로세스를 수행한다는 신뢰 속에서 이 모든 것이 작동되어야 합니다. 따라서, 보안, 신용, 신뢰성 있는 메시징은 어떤 SOA에서든 중요한 역할을 합니다.

참고자료:



위로


  서비스 지향 아키텍쳐의 활용

SOA의 필요성은 비즈니스 IT 시스템들이 비즈니스 변화에 대해 보다 민첩하게 대처해야 한다는 필요성에서 생겨났습니다. 확정적인 관계를 받아들이지만 융통성 있는 스팩 구현으로 IT 시스템들은 기존 시스템들의 기능을 활용할 수 있고, 앞으로의 변화에 대응할 수 있습니다.

예를 들어, 500개의 국제적인 점포망을 소유하고 있는 의류 소매 조직은 패션에 발맞추기 위해서 디자인을 자주 바꾸어야 합니다. 스타일과 컬러 뿐만 아니라 재질, 제조, 운송 부분 까지도 변경해야 합니다. 소매업체와 제조자 간 시스템이 호환되지 않는다면, 한 공급자에서 또 다른 공급자로의 변경은 매우 복잡한 소프트웨어 프로세스가 될 수 있습니다. WSDL 인터페이스는 융통성이 있기 때문에 각 기업들이 그들의 기존 시스템을 유지하도록 하고, 대신 WSDL 인터페이스에 맞추어 새로운 서비스 레벨 계약을 체결하도록 합니다. 소프트웨어 애플리케이션을 모두 재구현 할 필요가 없습니다. 이것은 비즈니스의 수평적 변화로서 파트너와 모든 비즈니스 작동을 변경하는 것입니다. 비즈니스 인터페이스는 약간 변경되고 내부 작동까지는 변경될 필요가 없기 때문에 외부적으로 협업할 수 있는 것입니다.

또 다른 형태는 내부 변화(internal change)입니다. 소매업체가 체인 소매점 내에 장소를 빌려 부띠크 판매자에게 제공하기로 결정할 수 도 있습니다. 이것은 점포 내 점포(store-in-store) 비즈니스 모델입니다. 이 기업의 대부분의 비즈니스 기능은 같지만 이제는 새로운 내부 소프트웨어로 임대 계약을 맺어야 합니다. 내부적으로 소프트웨어 시스템은 정비중이더라도 기존 공급자의 시스템과의 인터랙팅에 심각한 영향을 주지 않고 이를 수행해야 합니다. 이 경우 SOA 모델은 그대로 보존되는 반면 내부 구현이 변합니다. SOA 모델에 새로운 상(aspect)이 추가되어 임대 계약에 대한 새로운 책임이 추가되지만, 일반적인 소매 관리 시스템은 변화가 없습니다.

내부 변화에 대한 개념을 확대시키기 위해 IT 관리자들은 다른 방식으로 사용될 수 있는 새로운 소프트웨어 구성 방법을 찾을 수 있습니다. 이를 테면, 광고용 임대 포스터 공간이 이에 해당됩니다. 유연한 SOA 모델에서 생성된 새로운 비즈니스 제안은 이 새로운 디자인에 재적용 됩니다. 이것은 SOA 모델의 새로운 결과물이고, 전에는 불가능했던 새로운 기능이라 할 수 있습니다.

수직적 변화 역시 가능합니다. 소매업자가 자신의 옷을 판매하던 방식에서 매장내매장 모델을 통해 독점적인 임대 공간으로 옮길 수 있다. 수직적 변화의 경우 SOA 모델의 중대한 재구성이 수반되어야 합니다. 아마도 새로운 시스템, 소프트웨어, 프로세스, 관계들이 필요합니다. 이 경우 SOA 모델의 장점은 애플리케이션과 프로그램의 관점이 아닌 비즈니스 기능과 프로세스의 관점에서 작용하여 비즈니스 기능에 기반하여 추가되고, 변경되고 제거되어야 할 것이 무엇인지를 명확하게 구분할 수 있게 됩니다. 소프트웨어 시스템은 비즈니스 프로세스에 맞춰 구성될 수 있습니다.

주지하듯이, 변화와, 이 변화를 받아들이는 SOA 시스템의 능력은 가장 중요한 요소입니다. 개발자에게 그와 같은 변화는 그들의 작업 내부 또는 외부에서 발생할 수 있습니다. 인터페이스가 정의되는 방법과 서로 인터랙팅 하는 방법에 관한한 그렇습니다. 오히려 개발자 보다는 SOA 모델에 대부분의 변화를 일으키는 것은 아키텍트의 역할 입니다. 개발자들이 서비스로 정의된 기능 단위를 만드는데 초점을 맞춘다면 아키텍트와 모델러는 그 단위를 조합하는 것과 Universal Modeling Language (UML)를 통해 일반적으로 표현하는 것과 Model-Driven Architecture (MDA)로 기술하는 것에 초점을 맞추고 있습니다.

참고자료:



위로


  SOA의 컴포넌트 기술

SOA는 그 자체로 소프트웨어가 함께 놓이는 방식에 대한 추상적 개념입니다. 소프트웨어 형태로 존재하기 위해서는 XML과 웹 서비스로 구현된 보다 구체적인 개념과 기술에 의존합니다. 또한, 보안, 정책 관리, 신뢰성 있는 메시징, 계정 시스템 등이 효과적으로 작동해야 합니다. 분산 트랜잭션 프로세싱과 분산 소프트웨어 상태 관리를 통해 이 부분을 향상시킬 수 있습니다.

SOA 서비스와 웹 서비스의 차이는 디자인에 있습니다. SOA 개념은 서비스가 특별하게 인터랙팅 하는 방식을 정확하게 정의하지 않습니다. 단지 서비스들이 서로를 인식하고 인터랙팅 하는 방법만 정의합니다. 프로세스가 수행되는 방법 전략을 정의하는 것과 실제로 수행되는 방법 전략에는 차이가 있습니다. 반면 웹 서비스는 서비스들간 메시징이 인터랙팅 되는 방식에 대한 특정 가이드라인을 제시하고 있습니다. SOA 모델의 전략적 구현은 HTTP를 통해 전달되는 SOAP 메시지에서 일반적으로 볼 수 있습니다. 따라서 웹 서비스는 SOA가 구현되는 방식의 일부라고 할 수 있습니다.

SOA는 웹 서비스로 제한되어 있습니다. WSDL로 서비스 인터페이스를 직접 구현하고 XML 메시지와 통신하는 다른 프로토콜은 SOA에 포함될 수 있습니다. CORBA와 IBM의 MQ 시스템들은 SOA에 참여하여 WSDL로 작동하는 새로운 기능을 사용하고 있습니다. 두 서비스가 데이터를 교환하려 한다면 같은 메시징 프로토콜을 사용해야 하지만 데이터 인터페이스는 같은 정보 교환을 허용합니다.

모든 메시징을 적절하게 제어하고 보안, 정책, 계정 등을 적용하려면 SOA 아키텍쳐의 그림에 들어갈 새로운 비즈니스 객체가 필요합니다. 이것은 Enterprise Service Bus f(ESB)이고, 제어 서비스들 간 모든 메시지의 흐름과 통역을 맡고 있으며 모든 가능한 메시징 프로토콜을 사용합니다. ESB가 절대적으로 필요한 것은 아니지만 SOA에서 비즈니스 프로세스를 적절하게 관리하는 중요한 컴포넌트입니다. ESB는 그 자체로 하나의 엔진이거나 많은 피어와 하위 피어들로 구성된 분산 시스템일 수도 있습니다. 개념상으로 Message Queue와 분산 트랜잭션 컴퓨팅 같은 이전 컴퓨터 과학 개념에서 나온 store-and-forward 메커니즘에서 진화한 것입니다.

개발자 측면에서 그들이 사용하는 툴은 SOA의 기능에 대해 인지하고 있어야 하고 개발자가 SOA 객체를 사용하여 효과적으로 작업할 수 있도록 해야 합니다. SOA 모델의 디자인 프로세스, 서비스와 서비스 객체의 개발, SOA 애플리케이션의 테스팅이 이에 해당합니다. 따라서 개발자 툴은 Service-Oriented Application Design/Development (SOAD)를 위한 준비를 해야 합니다.

참고자료:



위로


  SOA와 다른 기술의 연관 방법

SOA는 다양한 많은 기술들과 인터랙팅 할 수 있지만 여기에서는 중요한 역할을 하는 컴포넌트의 캡슐화와 집합에 대해서 이야기 하겠습니다. 앞서 언급했지만, SOA 서비스는 단순한 객체, 복잡한 객체, 객체들의 집합, 많은 객체들을 포함하고 있는 프로세스, 다른 프로세스들을 포함하는 프로세스, 하나의 결과를 내는 애플리케이션의 전체 집합 등 이 모든 것이 될 수 있습니다. 서비스 밖에서는 하나의 엔터티로 보이지만 내부에서는 필요한 만큼의 복합적 레벨을 포함할 수 있습니다. 퍼포먼스의 관점에서 보면 대부분의 SOA 서비스들은 단순한 객체의 세분성으로까지는 내려가지 않고 큰 컴포넌트의 중간 정도에 더 잘 맞습니다.

SOA는 XML과 WSDL을 제외하고는 언어 스팩이 아닙니다. WSDL을 생성하고 인터랙팅 할 수 있는 한 어떤 프로그래밍 언어로도 구현될 수 있습니다. SOAP 그 자체는 절대적 필요조건은 아니지만 일반적인 메시징 시스템입니다. 따라서 SOA의 멤버 서비스들은 WSDL을 지원하는 다양한 프로그래밍 언어와 플랫폼에서 구현될 수 있습니다.

Common Object Broker Request Architecture (CORBA) 기반 애플리케이션은 SOA에 인터페이싱을 하기위한 많은 필수 컴포넌트들이 있습니다. CORBA의 Interface Description Language (IDL)은 개념적으로는 WSDL과 비슷하지만 정확하지 않기 때문에 WSDL로 우선 매핑되어야 합니다. 게다가 프로세스와 정책 관리 같은 SOA의 고급 프로토콜이 사용되어야 합니다. 서비스로 표현되는 CORBA 컴포넌트가 SOA 서비스와 인터랙팅 해야 할 경우입니다. CORBA 모델 내에서는 모든 개별적인 하위 컴포넌트들은 전과 같이 작동할 수 있습니다.

Object Management Group이 제안하고 다양한 IBM Rational 제품들을 사용하여 구현된 Model-Driven Architecture (MDA)는 보다 추상적인 레벨에서는 SOA의 개념과 강력한 상관관계를 갖고 있습니다. MDA는 어떤 소프트웨어 프로세스든 모델과 메타모델로 정의될 수 있다는 개념에 기반합니다. 따라서 MDA는 플랫폼 상에서 실행될 수 있는 실행파일로 컴파일 될 수 있는 소프트웨어 애플리케이션으로 컴파일 된 모델을 만듭니다. MDA는 서비스 개념과 객체 개념을 구별하지 않지만 모델이 다른 모델의 하위세트로 구성되는 것을 허용합니다. SOA의 핵심 컴포넌트인 BPEL 내의 프로세스 집합과 비슷한 개념입니다.

SOA와 웹 서비스는 프로그래밍 언어에 독립적이지만 그 중에서도 자바가 많이 쓰이고 있습니다. 정의가 잘 된 자바 인터페이스와 풍부한 자바로 구현된 다양한 프로토콜은 자바 개발자들이 모델을 구현할 때 도움이 됩니다. 여기에서 자바는 각 서비스의 기능 개발에 중요한 역할을 하고 데이터 객체들과, 서비스 내에서 논리적으로 캡슐화 된 다른 객체들의 인터랙션을 조작합니다.

SOA와 웹 서비스의 또 다른 핵심 관계는 자율 컴퓨팅과 그리드 컴퓨팅의 개념입니다. 자율 컴퓨팅 개념은 분산 서비스 아키텍쳐의 관리에 적용되고, 특히 정책과 서비스 레벨 계약을 관리하는데 도움이 됩니다. 게다가 SOA 시스템의 전체적 안정성에도 기여합니다.

그리드 컴퓨팅은 두 가지 레벨의 SOA 시스템에 작용합니다. 분산 컴퓨팅 형태로 되어있는 그리드는 분산 특징과 서비스들과의 인터랙션을 활용하여 SOA 애플리케이션을 전산적으로 지원합니다. 이러한 방식으로, 그리드 서비스는 개별 서비스들이 구현될 수 있는 프레임웍이 되는 것입니다. 따라서 SOA 애플리케이션은 그리드 서비스의 소비자가 될 수 있습니다.

그리드 자체는 SOA에서 구현 될 수도 있습니다. 이 경우 각 운영 체계 서비스들은 전체 SOA 애플리케이션을 구성하는 멤버가 되는 것입니다. 따라서 그리드의 개별 컴포넌트들은 웹 서비스를 사용하여 통신하고 SOA의 형태로 인터랙팅 합니다. 요약하면, 그리드 시스템은 SOA 그 자체가 될 수도 있고, 그 상단에 구현된 애플리케이션 레벨의 SOA 모델을 제공합니다.

참고자료:



위로


  애플리케이션에서 SOA 활용하기

SOA를 활용할 부분은 소프트웨어 개발 프로세스 뿐만 아니라 비즈니스 개발 프로세스도 포함됩니다. 특정 소프트웨어 서비스를 구현할 수 있는 네 가지 SOA 채택 레벨이 있습니다. 이 모두가 비즈니스 모델을 온 디맨드 시스템으로 변형하는 것입니다. 자세한 정보는 The Four levels of SOA Adoption 기술자료를 참조하십시오.

첫 번째 레벨은 가장 간단합니다. 개별 서비스를 구현하는 것이 이 레벨에 포함되어 있습니다. New to Web services에 자세한 자료가 소개되어 있습니다.

두 번째 레벨에서, 서비스를 만들 수 있고 비즈니스 기능들을 SOA에 통합할 수 있습니다. 애플리케이션 통합, 정보 통합, 프로세스 통합, 전체 시스템 통합 등의 여러 통합 단계가 있습니다. Migrating to a Service-Oriented Architecture를 참조하시기 바랍니다.

세 번째 레벨은 자신의 엔터프라이즈 IT 인프라를 SOA 모델로 변형하는 것입니다. 네 번째 채택 레벨은 비즈니스 모델을 온 디맨드로 변형하는데 초점을 맞추고 있습니다.

IT 실무자 관점에서, SOA 애플리케이션을 구현하기 위해서는 일반적으로 네 가지 단계를 거쳐야 합니다: 구현, 전개, 사용, 관리. 구현 단계에서는 비즈니스 모델 또는 프로세스, 소프트웨어 모델과 SOA 모델을 정의합니다. 그런 다음, 일반적인 인터페이스로 재사용 할 수 있는 서비스를 만듭니다.

전개 단계에서는 구현된 서비스들을 실행 및 관리 환경으로 배치하는 것입니다. 사용 단계에서는 앞서 정의된 SOA와 소프트웨어 모델에 따라 애플리케이션을 조립하고 소프트웨어 품질과 퍼포먼스, 확장성 같은 비 기능적 사항들을 테스트합니다. 이 정도 진행되면 전개되어 사용자들이 사용할 수 있습니다. 마지막 관리 단계에서는 보안과 사용을 감시 및 관리하고 서비스 레벨 계약과 정책과 비교하여 퍼포먼스를 비교합니다.

이상은 SOA의 개념적인 단계입니다. 이 단계와 실제 환경의 단계를 비교하면 SOA 애플리케이션 생성에 개입된 다양한 역할들이 있습니다. 같은 일 또는 여러 팀 멤버, 심지어는 여러 팀들 내에서 역할이 주어집니다. 역할 개념은 Rational Unified Process (RUP)으로 구별되는 역할로 표현됩니다.

RUP 역할에는 프로젝트 매니저, 분석가, 아키텍트, 모델러, 개발자, 테스터, 개발 및 운영자 등이 있습니다. SOA는 개념상의 SOA 모델을, SOA 모델과 IT 인프라의 리소스와 비교하여 테스트하는 SOA Modeler 역할을 추가하여 거의 동일하게 매핑하고 있습니다. 개발자는(사용 단계의) 어셈블러로서의 부차적인 역할을 합니다. 개별 서비스들을 이용하여 정의된 모델에 따라 실제 SOA 애플리케이션을 구현하는 것입니다. 이러한 역할들은 SOA를 사용하는 엔터프라이즈 내에 존재하고 있습니다.

참고자료:



위로


  SOA 기술력 개발하기

정보 분석가, 소프트웨어 아키텍트, 소프트웨어 개발자, 소프트웨어 품질 분석가, 시스템 관리자 등 역할에 따라 기술이 다릅니다. SOA의 개념은 이 모든 역할까지 확장됩니다. 따라서 각 역할이 어떻게 작동하는지에 대해서는 이해해야 합니다. 그 다음에는 각 역할이 갖춰야 하는 기술 개념에 익숙해져야 합니다.

정보 분석가와 소프트웨어 아키텍트는 모델 중심 아키텍쳐와 UMM 2.0을 이해해야 합니다. 소프트웨어 개발자와 프로그래머는 웹 서비스와 MQ 그리고 기타 프로토콜의 프로그램 방식의 인터페이스, 보안 인터랙션 방식, 워크플로우 프로세싱 개념을 자세히 알아야 합니다. 품질 분석가와 시스템 관리자는 SOA 프로세스 모델 대 실제 SOA 기능 아키텍쳐 구현에 대한 이해도를 높여야 합니다. 개별 서비스들이 분산 애플리케이션의 전체 퍼포먼스에 미치는 영향에 대해서도 알고 있어야 합니다. 시스템 관리자는 애플리케이션 보안과 신용 모델이 어떻게 작동하는지, 그리고 애플리케이션이 운영 체계와 네트워크 시스템에 영향을 미치는 정책에 어떤 영향을 미치는 지도 알아야 합니다.

참고자료:



위로


  SOA에 활용할 수 있는 IBM 툴과 제품들

IBM은 SOA 기반 IT 시스템들을 구현, 전개, 관리하는데 필요한 툴, 교육, 서비스를 제공한 첫 벤더입니다. 서비스의 구현, 전개, 사용 관련한 툴을 포함하여 전체 수명 주기의 모든 측면을 아우르고 있으며 다양한 레벨의 SOA를 채택하고 있습니다. 각 레벨은 하위 채택 레벨과 소프트웨어를 포함하고 있습니다. 모든 수명주기 단계가 모든 채택 레벨에 필요한 것은 아닙니다. 프로세스의 범위가 다르기 때문입니다. 마지막으로 On Demand Business Transformation의 네 번째 레벨은 비즈니스 지향이며, 하위 레벨에 소프트웨어가 포함되어 있습니다.

웹 서비스 구현의 첫 번째 SOA 채택 레벨에서 그림 1에 나타난 툴은 간단한 웹 서비스의 생성과 운영에 도움이 됩니다.

그림 1. 개별 웹 서비스 구현하기 vs 핵심 컴포넌트
Figure 1. Implementing Individual Web services -- Core Components

두 번째 레벨인 서비스 지향 통합에서 툴은 다중의 서비스들을 발견하고 이들과 인터랙팅하고, SOA 모델의 기초를 만드는 수단을 제공하는 것으로 옮겨가고 있습니다. 그림 2a는 레벨 2 채택의 핵심 컴포넌트이지만, 그림 2b는 레벨 2에 도움이 되는 추가 컴포넌트 입니다.

그림 2a. 서비스 지향 통합 vs 핵심 컴포넌트
Figure 2a. Service Oriented Integration -- Core Components

그림 2b. 서비스 지향 통합 vs 추가 컴포넌트
Figure 2b. Service Oriented Integration -- Add-on Components

레벨 2인 엔터프라이즈 중심의 IT 변형에서 IBM은 광범위한 SOA와 웹 서비스 제품을 제공하여 모든 IT 시스템 기능들을 사용할 수 있도록 하고, SOA 시스템의 엔터프라이즈 중심의 관리용 프레임웍을 제공합니다. 그림 3a는 레벨 2 채택의 핵심 컴포넌트와 그림 3b의 추가 컴포넌트입니다.

그림 3a. 엔터프라이즈 중심의 IT 변형 vs 핵심 컴포넌트
Figure 3a. Enterprise Wide IT Transformation -- Core Components

그림 3b. 엔터프라이즈 중심의 IT 변형 vs 추가 컴포넌트
Figure 3b. Enterprise Wide IT Transformation -- Add-on Components

참고자료:


'java' 카테고리의 다른 글

jxl 을 이용하여 images 가져오기  (0) 2008.09.16
SOA 기술자료 특집 - IBM developerworks  (0) 2008.09.10
Junit의 TestSuite  (0) 2008.09.02
Connection Pool - DBCP  (0) 2008.09.01
ZK - Ajax but no JavaScript  (0) 2008.08.29
Posted by marryjane
|

Junit의 TestSuite

java 2008. 9. 2. 14:19

http://shoutrock.egloos.com/4344090

프로젝트를 진행하다 보면 테스트 케이스가 수십개에서 수백개가 된다.
이러한 경우 이를 TestSuite가 grouping을 한다.
public static Test suite(){
    TestSuite suite = new TestSuite();
    suite.addTestSuite(Test1.class);
    suite.addTestSuite(Test2.class);    
    return suite;
}

public static vois main(String args[]){
    junit.textui.TestRunner.run(suite());
}

위와 같이 addTestSuite() 메소드를 이용해서 하나 이상의 단위 테스트 케이스를 하나로 grouping할 수 있도록 한다.
TestSuite를 작성하고, 이 TestSuite.addTestSuite() 메소드로 하나 이상의 TestSuite 또는 하나 이상의 TestCase를 상속한 테스트 클래스를 지정한다.
이를 실행하면 main()에서 JUnit의 TestRunner가 실행되고 이 때 지정한 테스트 케이스가 순서대로 실행된다.

출처 : Enterprise Java Beans 3.0  - 김병곤 저  - 가메출판사

'java' 카테고리의 다른 글

SOA 기술자료 특집 - IBM developerworks  (0) 2008.09.10
SOA와 웹서비스 입문 (한글) - IBM developerworks  (0) 2008.09.10
Connection Pool - DBCP  (0) 2008.09.01
ZK - Ajax but no JavaScript  (0) 2008.08.29
Java POI 예제소스  (0) 2008.08.26
Posted by marryjane
|

Connection Pool - DBCP

java 2008. 9. 1. 20:33

http://commons.apache.org/dbcp/

commons-dbcp.jar
commons-pool.jar
commons-collections.jar : 1.2.2 에서는 필요치 않음.

BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(…);
ds.setUrl(…);
ds.setUserName(…);
ds.setPassword(…);

......
Connection conn = ds.getConnection();

......
conn.close();

'java' 카테고리의 다른 글

SOA와 웹서비스 입문 (한글) - IBM developerworks  (0) 2008.09.10
Junit의 TestSuite  (0) 2008.09.02
ZK - Ajax but no JavaScript  (0) 2008.08.29
Java POI 예제소스  (0) 2008.08.26
jdbc 1.0 ~ 3.0  (0) 2008.08.05
Posted by marryjane
|

ZK - Ajax but no JavaScript

java 2008. 8. 29. 13:22

http://www.zkoss.org/
http://www.potix.com/zkdemo/userguide/


ZK is the most proven Ajax + Mobile framework designed to maximize enterprises operation efficiency and minimize the development cost.


With groundbreaking Direct RIA architecture, ZK simplifies and speeds the creation, deployment and maintenance of rich Internet applications.


By programming user interfaces directly, developing Web application isas intuitive as programming desktop applications. By programmingdatabase and enterprise resource access directly, developers no longerhave to worry about exposure of business logic to the client andexposure of business data over the Internet .


'java' 카테고리의 다른 글

Junit의 TestSuite  (0) 2008.09.02
Connection Pool - DBCP  (0) 2008.09.01
Java POI 예제소스  (0) 2008.08.26
jdbc 1.0 ~ 3.0  (0) 2008.08.05
SI 프로젝트에서도 애자일 프로세스는 가능한가?  (0) 2008.07.28
Posted by marryjane
|

Java POI 예제소스

java 2008. 8. 26. 11:13

/**
* 작성자 : litwave
* 작성일 : 2008. 08. 21
* 참고 Site :
*   http://poi.apache.org/hssf/quick-guide.html#Autofit
*   http://poi.apache.org/apidocs/index.html
*   http://blog.naver.com/btchae?Redirect=Log&logNo=80005156571
*/

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;

public class ExcelFormatAdapter {
  private HSSFWorkbook wb;
  private HSSFSheet [] sheets;

  private final int ROW_POSITION = 1;
  private final int COL_POSITION = 1;

  public ExcelFormatAdapter(String[] sheetNames, String title, String author, String[] header, int [] length) {
    wb = new HSSFWorkbook();
    sheets = new HSSFSheet[sheetNames.length];
    for(int index=0; index < sheetNames.length; index++) {
      sheets[index] = wb.createSheet(sheetNames[index]);
      makeHeader(index, title, author, header, length);
    }
  }

  public void makeTailCell(int sheetIndex, int rowIndex, int valueCount, String currentDate) {
    int dataRowIndex = ROW_POSITION + 3 + rowIndex;
    HSSFRow row = sheets[sheetIndex].createRow(dataRowIndex);

    // 데이터 를 입력한다.
    for(int index=0; index < valueCount; index++) {
      if(index == valueCount -1) {
        createTailCell(row, COL_POSITION + index, "출력일자 : " + currentDate);
      } else {
        createTailCell(row, COL_POSITION + index, "");
      }
    }
  }


  /**
   * 마지막에 출력할 출력일자 셀을 설정한다.
   * @param row
   * @param column
   * @param value
   */
  private void createTailCell(HSSFRow row, int column, String value) {
    HSSFCell cell = row.createCell((short)column);
    HSSFRichTextString richValue = new HSSFRichTextString(value);
    cell.setCellValue(richValue);
    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
    cell.setCellStyle(getTailStyle());
  }

  private HSSFCellStyle getTailStyle() {
    // font를 설정한다.
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 10);
    font.setFontName("돋움");

    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
    style.setFont(font);
    style.setBorderTop(HSSFCellStyle.BORDER_THIN);

    return style;
  }


  public void makeDataCell(int sheetIndex, int rowIndex, String [] values) {
    int dataRowIndex = ROW_POSITION + 3 + rowIndex;
    HSSFRow row = sheets[sheetIndex].createRow(dataRowIndex);

    // 데이터 를 입력한다.
    for(int index=0; index < values.length; index++) {
      createDataCell(row, COL_POSITION + index, values[index]);
    }
  }

  /**
   * 데이터 셀을 설정한다.
   * @param row
   * @param column
   * @param value
   */
  private void createDataCell(HSSFRow row, int column, String value) {
    HSSFCell cell = row.createCell((short)column);
    HSSFRichTextString richValue = new HSSFRichTextString(value);
    cell.setCellValue(richValue);
//    cell.setCellStyle(getDataStyle());
  }

  private HSSFCellStyle getDataStyle() {
    // font를 설정한다.
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 10);
    font.setFontName("돋움");

    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_LEFT);

    style.setFont(font);

    return style;
  }

  private void makeHeader(int sheetIndex, String title, String author, String[] header, int [] length) {
    HSSFRow row = sheets[sheetIndex].createRow(ROW_POSITION);
    // Title을 만들어 준다.
    createTitleCell(row, COL_POSITION, title);
    sheets[sheetIndex].addMergedRegion(new Region(ROW_POSITION, (short)COL_POSITION, ROW_POSITION, (short)header.length));

    // 작성자 셀을 설정한다.
    row = sheets[sheetIndex].createRow(ROW_POSITION + 1);
    createAuthorCell(row, COL_POSITION + header.length -1, "작성자 : " + author);

    sheets[sheetIndex].setColumnWidth((short)0, (short) ( ( 50 * 1 ) / ( (double) 1 / 20 )));

    // 데이터 Header를 입력한다.
    row = sheets[sheetIndex].createRow(ROW_POSITION + 2);
    for(int index=0; index < header.length; index++) {
      sheets[sheetIndex].setColumnWidth((short)(COL_POSITION + index), (short) ( ( 50 * length[index] ) / ( (double) 1 / 20 )));
      createHeaderCell(row, COL_POSITION + index, header[index]);
    }
  }

  /**
   * Header 셀을 설정한다.
   * @param row
   * @param column
   * @param value
   */
  private void createHeaderCell(HSSFRow row, int column, String value) {
    HSSFCell cell = row.createCell((short)column);
    HSSFRichTextString richValue = new HSSFRichTextString(value);
    cell.setCellValue(richValue);
    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
    cell.setCellStyle(getHeaderStyle());
  }

  private HSSFCellStyle getHeaderStyle() {
    // font를 설정한다.
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 10);
    font.setFontName("돋움");
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    font.setColor(wb.getCustomPalette().findSimilarColor((byte)0x00, (byte)0x00, (byte)0x00).getIndex());


    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

    style.setFont(font);

    style.setFillForegroundColor(wb.getCustomPalette().findSimilarColor((byte)0x99, (byte)0xCC, (byte)0xFF).getIndex());
    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    style.setBorderTop(HSSFCellStyle.BORDER_THIN);

    return style;
  }

  /**
   * 작성자 셀을 설정한다.
   * @param row
   * @param column
   * @param value
   */
  private void createAuthorCell(HSSFRow row, int column, String value) {
    HSSFCell cell = row.createCell((short)column);
    HSSFRichTextString richValue = new HSSFRichTextString(value);
    cell.setCellValue(richValue);
    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
    cell.setCellStyle(getAuthorStyle());
  }

  private HSSFCellStyle getAuthorStyle() {
    // font를 설정한다.
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 10);
    font.setFontName("돋움");

    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
    style.setFont(font);

    return style;
  }

  /**
   * 제목 셀을 설정한다.
   * @param row
   * @param column
   * @param value
   */
  private void createTitleCell(HSSFRow row, int column, String value) {
    HSSFCell cell = row.createCell((short)column);
    HSSFRichTextString richValue = new HSSFRichTextString(value);
    cell.setCellValue(richValue);
    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
    cell.setCellStyle(getTitleStyle());
  }

  private HSSFCellStyle getTitleStyle() {
    // font를 설정한다.
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 14);
    font.setFontName("돋움");
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    font.setColor(wb.getCustomPalette().findSimilarColor((byte)0xFF, (byte)0xFF, (byte)0xFF).getIndex());


    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

    style.setFont(font);

    style.setFillForegroundColor(wb.getCustomPalette().findSimilarColor((byte)0x00, (byte)0x80, (byte)0x80).getIndex());
    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

    return style;
  }

  public void write(OutputStream stream) throws IOException {
    wb.write(stream);
  }

  public static void main(String [] args) {
    String [] sheetNames = new String [] { "첫번째 시트" };
    String title = "타이틀";
    String author = "litwave";
    String createDate = "2008. 08. 21(목)";
    String [] header = new String [] { "제목 1", "제목2", "제목3" };
    int [] length = new int [] { 10, 15, 8 };

    ExcelFormatAdapter excelAdapter = new ExcelFormatAdapter(sheetNames, title, author, header, length);
    int index=0;
    for(; index < 10; index++) {
      excelAdapter.makeDataCell(0, index, new String [] { "data_" + index, "데이 터" + index, "테스트 " + index });
    }

    excelAdapter.makeTailCell(0, index, header.length, createDate);

    File f = new File("D:/Z02_temp/imsi/test.xls");
    FileOutputStream fos = null;
    try {
      fos = new FileOutputStream(f);
      excelAdapter.write(fos);

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if(fos != null) try { fos.close(); } catch (IOException e) { }
    }
  }
}

'java' 카테고리의 다른 글

Connection Pool - DBCP  (0) 2008.09.01
ZK - Ajax but no JavaScript  (0) 2008.08.29
jdbc 1.0 ~ 3.0  (0) 2008.08.05
SI 프로젝트에서도 애자일 프로세스는 가능한가?  (0) 2008.07.28
HTTPClient 3.0  (0) 2008.07.25
Posted by marryjane
|

jdbc 1.0 ~ 3.0

2008. 8. 5. 11:11

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


KSUG/자바지기 공동 주체 세미나를 진행했을 때 다음과 같은 질문을 받은 기억이 있다.

"지금 발표하고 있는 내용이 N사와 같은 곳에서만 가능하지 않을까요. SI 프로젝트에서는 힘들다고 생각하는데요. 어떻게 생각하시는지요?".

이와 같은 질문을 받고 나 또한 확신에 찬 답변을 하지 못했다.

"지금 세미나를 하는 것처럼 조금씩 변화시켜 나간다면 언젠가는 할 수 있지 않을까요? 작은 변화이지만 지금부터 만들어 나갔으면 좋겠습니다. 여러분 개개인이 변화하려는 노력을 보여주시면 좋을 것 같습니다."

정 확하게 기억이 나지 않지만 이와 같이 답변을 했던 것으로 기억한다. 나 또한 SI 프로젝트에서 애자일 프로세스를 적용하고 지속적 통합툴(CI)을 사용해본 경험이 없었기 때문이다. 현재 내가 일하고 있는 곳은 계약 관계에 의해서 프로젝트를 진행하는 것이 아니라 프로젝트에 참여하는 모든 구성원들이 같은 회사 사람이기 때문에 개발 프로세스를 선택하거나 개발 환경을 세팅하는 부분에 있어서는 자유로운 부분이 있다. 물론 그렇다고 완전히 자유로운 것도 아니다. 조직이 대규모화되면서 점차 정해진 프로세스에 따라 진행해야하는 부분도 많다. 하지만 계약 관계에 있는 SI 프로젝트보다는 새로운 시도를 해볼 수 있는 환경이 아직까지는 남아 있는 것이 사실이다.(개인적인 생각으로 몇년 이내에 이러한 자유조차 없어질 가능성도 있다.)

세미나가 끝나고 한 동안 다른 업무에 치이면서 잊고 지냈다. 그러던 중 "린 소프트웨어 개발:애자일 실천 도구 22가지 - 애자일 시리즈 003" 책을 다시 읽으면서 위 질문에 대한 해답을 어렴풋하게나마 찾을 수 있었다. 내가 직접 경험한 내용은 아니지만 이 책을 쓴 필자들을 신뢰하고 있기 때문에 충분히 소개할만하다고 생각한다.

SI 성으로 진행하는 국내 대부분의 프로젝트와 포털, 솔루션 개발 업체의 가장 큰 차이점은 계약 관계를 맺고 있느냐 그렇지 않느냐의 차이에 달려 있다. 포털이나 솔루션 개발 업체는 계약관계없이 프로젝트를 진행하는 경우가 대부분이기 때문에 프로젝트에 가장 적합하다고 판단되는 개발 프로세스와 개발 환경을 만들어 프로젝트를 진행할 수 있다. 특히 애자일 프로세스가 가능한 이유는 우선순위에 따라 개발을 진행하는 것이 가능하며, 우선 순위가 낮은 경우에는 다음 버전으로 미룰 수 있는 타협점이 있다는 것이다.

물 론 SI 프로젝트 또한 이 같은 타협점을 찾는 것이 가능하지만 계약관계에 있기 때문에 힘든 것이 사실이다. 특히 국내 소프트웨어 개발 환경에서는 갑의 한마디로 인해 무수히 많은 부분이 한순간에 뒤바뀌어 버릴 수 있다는 것이다. 불합리한 부분이 있음에도 불구하고 주종관계에 있기 때문에 을,병 입장에서는 거절하기 힘든 것이 사실이다. 국내에서 진행하는 많은 SI 프로젝트들이 성공이라는 이름으로 포장을 하고 있지만 뚜껑을 열어보면 80~90% 이상이 실패한 프로젝트일 것이라 생각한다. 물론 근거 자료를 제시하라고 한다면 제시할 근거는 없다. 어디에도 실패했다고 이야기하는 프로젝트를 본적이 없기 때문이다. 그러나 내가 참여했던 많은 프로젝트들이 성공했다고 포장은 했지만 실상은 실패했다고 생각하기 때문이다. 갑과 을이 서로간의 책임을 지지 않기 위하여 성공이라는 이름으로 포장하기 때문에 어쩔 수 없이 발생할 수 밖에 없는 상황이라고 생각한다.

어차피 성공이라는 이름으로 포장을 하지만 프로젝트 오픈후에 무수히 많은 밤을 지세우면서 고생하는 개발자들을 생각하면 마음이 아프다. 또한 1차로 끝나지 않고 2차, 3차, 4차로 이어지는 Never Ending 프로젝트들 또한 발생하고 있는 것이 사실이다.

계약 직 개발자로서 지내던 시간이 생각나 잠시 삼천포로 빠졌다. 다시 본론으로 들어가서 SI 프로젝트에서 애자일 프로세스를 적용하기 위하여 필요한 부분은 현재의 계약 방식을 바꿔야 한다는 것이다. 지금은 프로젝트의 요구사항도 분석하지 않은 상태에서 계약이 이루어지는 경우가 대부분이다. 그러나 이런 상태에서 어떻게 제안을 하고 계약을 맺을 수 있겠는가? 이와 같이 계약이 이루어질 경우 갑은 정해진 기간과 금액 내에서 최대한 많은 기능을 요구할 것이 뻔하며, 을은 갑의 요구사항에 최대한 방어하면서 더 빠른 기간내에 프로젝트를 완료해야 자신의 이익을 증가시킬 수 있는 것은 명백한 사실이다. 이와 같은 상황이기 때문에 프로젝트 PM 능력이 변경 가능성을 최대한 방어하고 고객의 요구사항을 최대한 잘라버릴 수 있는 능력으로 판단되는 경우가 대부분이다. 물론 개발자들을 얼마나 늦게까지 퇴근시키지 않고 최대한 빨아 먹을 수 있을때까지 최대한 빨아 먹을 수 있는 것을 능력으로 생각하는 몰지각한 PM들도 많이 있다. 그런 PM들에게는 엿이나 먹고 떨어지라고 한마디 하고 싶다.

린 소프트웨어 개발 책의 242~264페이지까지 이 책의 마지막 실천 도구인 22번째 계약에 관련한 내용이 나온다. 이 책에서는 계약의 종류를 고정 가격 계약(현재 국내에서 가장 많이 이루어지는 계약 형태), 시간 자재 계약, 단계적 계약, 목표 비용 계약, 목표 일정 계약, 이익 공유 계약으로 분류하고 있다. 이 책을 두번째 읽고 있지만 이렇게 많은 계약의 종류가 있는지 처음 알았다. 사실 첫번째 책을 읽을 때는 계약이 나와 관계 없는 일이라 생각하고 무시하고 넘어갔던 것 같다. 하지만 두번째 읽으면서 세미나 때의 질문에 대한 해답이라는 생각이 들면서 더 관심을 가지면서 읽을 수 있었다.(질문을 주신분께 개인적으로 감사의 말을..)

이 책에서는 애자일 프로세스에서 사용할 수 있는 계약 형태를 다음과 같이 보고 있다.

  • 시간 자재 계약은 동시 개발 방법을 쓰며, 가장 우선 순위가 높은 기능을 먼저 개발하고 동작하는 통합 코드를 각 반복 주기에서 전달하여 고객이 범위를 제한함으로써 비용을 쉽게 조정할 수 있게 하는 방법이다.
  • 단계적 계약은 주계약을 이용하여 각 반복주기에서 릴리스하게 한다. 동시 개발에서 중점을 두는 것처럼 각 단계에서 높은 우선순위 기능을 먼저 개발하고 동작하는 통합 코드를 각 반복 주기에서 전달하는 방법이다.
  • 목표 비용 계약은 양측의 일선 작업자에게 목표 비용을 맞추는 선에서 문제에 대한 해결책을 찾는 데 서로 협력할 수 있는 권한을 부여하고, 비용 안에서 목표를 달성하기 위해 범위를 제한할 자유를 부여하는 것이 기본 메커니즘인 방법이다.
  • 이익 공유 계약은 시간이 지남에 따라 상호 이익을 위해서 양측이 하는 일을 수정할 수 있다는 가정 하에 이루어진다.
린 소프트웨어 263페이지에서..


위 네가지 방법 중에서는 이익 공유 계약이 갑과 을 모두의 이익을 보장할 수 있으며, 프로젝트를 성공으로 이끌 수 있는 것으로 소개하고 있다. 물론 프로젝트의 성격에 따라 달라질 수도 있겠지만서도..위 네가지 계약 형태의 공통점은 모두 범위를 상세하게 결정하지 않은 상태로 계약을 맺는다는 것이다. 이는 돈에 대한 결정을 최대한 늦추는 형태를 가지는 것이다.

국내에서 위와 같은 형태의 계약 방식이 가능할까? 물론 선도적인 기업들은 위와 같은 형태의 계약을 통해서 높은 가치를 발휘하는 소프트웨어를 만들어낼 것이다. 그러나 단기적인 이익에만 집착하는 국내의 대다수 회사들은 꿈도 꾸지 못할 계약 방식일 것이다. 이미 이와 유사한 계약 형태를 한 경험이 있거나 하고 있다면 이 글의 트랙백을 통하여 자랑스럽게 소개하기 바란다. 아마도 국내의 좋은 개발자들이 해당 프로젝트에 지원하지 않을까 생각한다. 현재의 하청 구조의 프로젝트 진행 방식에서는 더더욱 힘든 계약 형태이며, 을에 해당하는 대형 SI(S사, L사, C사 등등) 업체들은 이런 형태의 계약을 하고 싶은 욕심 또한 없는 듯 싶다. 대형 SI 업체들이 그런 변화를 원했다면 국내 개발자들에게도 많은 혜택이 있었을 것으로 생각하나 온라인 상의 어느 곳을 찾아봐도 위와 유사한 계약 사례를 찾아볼 수 없다는 것이 안타깝다.

갑 또한 변화할 필요가 있다. 지금까지의 계약 형태인 고정 가격 계약으로 진행한 프로젝트들에 만족하는가? 아마 대부분 만족하지 못할 것이다. 만족하지 못하는 것은 문제가 있는 형태로 계약이 맺어졌기 때문이다. 자신들이 진정 원하는 소프트웨어를 만들고 싶다면 갑이 나서서 다른 형태의 계약을 하는 것도 좋은 선택이 될 것이다. 그런 변화의 자세없이 기존의 관행을 반복한다면 영원히 만족하는 소프트웨어를 볼 수 없을지도 모른다. 현재 자리를 좀 더 오래 지키고 싶다면 기존의 계약 형태를 바꾸기 위하여 노력해보라. 좋은 소프트웨어 개발을 통한 회사의 효율성 증대는 회사내에서 자신의 생명을 연장시켜 줄 것이다. 지금까지의 관행을 실천하기는 쉬울 것이다. 그러나 회사내에서 그저 그런 사원이 될 것이며, 그저 그런 회사로 남을 수 밖에 없을 것이다. 개떡 같은 소프트웨어를 만들고 싶지 않다면 갑 너 자신부터 변화하는 모습을 보여라.(오해할지 모르지만 현재 나 또한 갑이다. 물론 계약관계를 맺는 경우는 거의 없지만..)

개발 자들이 생각할 부분은 고정 가격 계약으로 맺어진 프로젝트에 섣부르게 애자일 프로세스를 적용하지 마라. 괜시리 적용했다가 모든 책임을 혼자 뒤집어 쓸수도 있다. 개발 환경을 자동화하는 부분에 있어서는 적극적으로 찬성하지만 애자일 프로세스의 적용에서는 다소 소극적인 입장을 취하고 싶다. 개발자들이 피해보는 상황은 만들고 싶지 않기 때문이다. 애자일 프로세스를 적용하고 싶지만 적용하지 못하는 것을 자신의 능력 부족 탓으로 돌리지는 말았으면 좋겠다. 개떡 같은 갑과 개떡 같은 을..그리고 개떡 같은 시대에 태어났기 때문에 겪는 문제이거니 생각하면 좋을거 같다. 하지만 그런 속에서도 지속적으로 변화를 만들어가고자 한다면 조금씩 변화의 모습은 나타나지 않을까? 개발자들이 언젠가는 관리자가 될 것이며, PM이 될 것이며, 갑이 될 수도 있기 때문이다.

개 떡 같은 환경을 탓하는 것도 좋지만 문제에 봉착했을 때 해결하려고 하지 않은 개떡 같은 우리들의 자세 또한 비판해 보기 바란다. 다른 사람들이 변화를 만들어주기 바라기 전에 자기 자신이 변화를 만들어가는 사람들이 많아졌으면 하는 바람이다. 그럼 나는 뭐하고 있냐고? 나 또한 개떡같은 내 자신을 비판하면서 좀 더 적극적으로 변화를 만들어 가려고 노력하고 있다.

PS. 언제나 갑이 될 수는 없을진데, 언제인가는 병이 될 수도 있을진데..오늘 갑과 을을 너무 씹었다. 아무래도 내가 갑의 자리에서 물러날 때는 이 글을 살포시 삭제해야 될까?  이런 글 하나 때문에 나와 같이 일하지 않는다면 나 또한 같이 일하고 싶지 않다. 분명 그네들은 개떡 같은게 아니라 개똥같이 쪼잔한 성격의 소유자들일 것이 분명하기 때문에..

'java' 카테고리의 다른 글

Java POI 예제소스  (0) 2008.08.26
jdbc 1.0 ~ 3.0  (0) 2008.08.05
HTTPClient 3.0  (0) 2008.07.25
URLConnection 와 HTTPClient  (0) 2008.07.25
javac 옵션  (0) 2008.07.09
Posted by marryjane
|

HTTPClient 3.0

java 2008. 7. 25. 18:02

3.0 혹은 3.1 사용 시. 4.0 은 포함되지 않는다.
원본 : http://programmers.tistory.com/entry/HTTPclient의-사용-1

#### 1. 설명 및 설치
1-1. HttpClient 소개
HttpClient은 HTTP상에서 커뮤니케이션을 하는 자바 기반의 어플리케이션 개발을 쉽게 할수 있도록 제공한다.
우리가 웹 브라우저 또는 그에 준하는 어플리케이션을 개발한다면 HttpClient은 우리에게 클라이언트 코드 개발에 도움을 줄수있다.
이름에서 의미하는것과 같이 HttpClient는 오직 HTTP 클라이언트 코드을 위한 컴포넌트이지 HTTP 요청을 처리하는 서버측 프로세스을 지원하지는 않는다.

1-2. 설치
현재 아파치 HttpClient 는 3.0.1 안정버전을 지원한다.
Jakarta Commons HttpClient 페이지에서 다운로드 받으면 된다.
(다운로드 페이지: http://jakarta.apache.org/commons/httpclient/downloads.html)
(최신버전 다운로드:
  - http://jakarta.apache.org/site/downloads/downloads_commons-httpclient.cgi
  - http://mirror.apache-kr.org/jakarta/commons/httpclient/binary/commons-httpclient-3.0.1.zip
)

commons-httpclient-3.0.1.zip 를 받아서 압축을 풀고,
commons-httpclient-3.0.1.jar 를 CLASSPATH 에 추가하면 된다.

1-3. 추가 설정(Dependencies)
http://jakarta.apache.org/commons/httpclient/dependencies.html

Artifact ID  Type  Version  Scope  URL  Comment 
commons-codec jar 1.2  http://jakarta.apache.org/commons/codec/
                       http://jakarta.apache.org/site/downloads/downloads_commons-codec.cgi
commons-logging jar 1.0.4  http://jakarta.apache.org/commons/logging/  
junit jar 3.8.1 test  http://www.junit.org/ 


#### 2. getMethod 사용 예제
=========================== GetSample.java =================================
package test.httpclient;

import java.io.FileOutputStream;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;

// Get Method를 사용한 예제
public class GetSample {

 // 가져올 페이지 주소, 네이버 뉴스 속보
 private static String url =
  "http://news.naver.com/news/list.php";
 
 
 // 파일에 byte[] 저장
 public static void saveBytes(String filepath, byte[] byteData) throws Exception
 {
  FileOutputStream foStream = null;
  try {
   foStream = new FileOutputStream(filepath);
   foStream.write(byteData);
  } finally {
   try { foStream.close(); foStream = null; } catch (Exception e) {}
  }
 }
 
 
 /**
  * @param args
  */
 public static void main(String[] args) {

  // HttpClient 생성
  HttpClient client = new HttpClient();


  // 요청 Method 지정
  HttpMethod method = new GetMethod(url);


  try {
   
   // QueryString 지정, 1.문자열
   url = url + "?mode=LSD&section_id=001&menu_id=001&view=1";
   // QueryString 지정, 2.NameValuePair 사용
//   NameValuePair nvp1= new NameValuePair("mode","LSD");
//   NameValuePair nvp2= new NameValuePair("section_id","001");
//   NameValuePair nvp3= new NameValuePair("menu_id","001");
//   NameValuePair nvp4= new NameValuePair("view","1");
//   method.setQueryString(new NameValuePair[]{nvp1,nvp2, nvp3, nvp4});

   System.out.println("QueryString>>> "+method.getQueryString());

   // HTTP 요청 및 요청 결과
   int statusCode = client.executeMethod(method);

   // 요청 결과..
   if (statusCode == HttpStatus.SC_OK) {
    System.out.println("요청 성공");
    System.out.println("응답 HTML:\n" + method.getResponseBodyAsString());
   
    // 결과 저장
    GetSample.saveBytes("naver_news.html", method.getResponseBody());
   } else if ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||
                 (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||
                 (statusCode == HttpStatus.SC_SEE_OTHER) ||
                 (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
    System.out.println("Redirecte !!!");
    System.out.println("Redirect target: " + method.getResponseHeader("location").getValue());
         }
   
  } catch (Exception e) {
   e.printStackTrace();
   
   // Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
   // commons-logging.jar, commons-logging-api.jar 를 CLASSPATH에 추가한다.
   
   // Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/codec/DecoderException
   // commons-codec-1.3.jar 를 CLASSPATH에 추가한다.
  }

 }

}

=========================== GetSample.java =================================


#### 3. postMethod 사용
GetMethod 나 PostMethod 나 사용방법은 비슷합니다.


PostMethod method = new PostMethod("http://xx.com/ex_login_ok.php");
NameValuePair userid = new NameValuePair("nick", "aaaaa");
NameValuePair userpw = new NameValuePair("password", "bbbb");

method.setRequestBody( new NameValuePair[] {userid, userpw});

client.executeMethod(method);


 

#### 4. Header 사용
헤더를 사용하기 위해서는 setRequestHeader() 를 이용하여 원하는 헤더를 정의해 주시면 됩니다.


String charset = null; // 기존 charset 사용
//String charset = "euc_kr"; // charset 지정

// 요청 헤더 설정
if (charset == null) {
    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
} else {
    method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + charset);
}


#### 5. Cookie 사용
아직 정리가 않되서.. 분량이 좀 많네요.^^;
찬찬히 정리하겠습니다.


#### Reference
1) 자카르타 프로젝트 HttpClient와 FileUpload 사용하기
  - http://blog.empas.com/inter999/read.html?a=3271313&l=1&v=trackback

'java' 카테고리의 다른 글

jdbc 1.0 ~ 3.0  (0) 2008.08.05
SI 프로젝트에서도 애자일 프로세스는 가능한가?  (0) 2008.07.28
URLConnection 와 HTTPClient  (0) 2008.07.25
javac 옵션  (0) 2008.07.09
IBM HOST CICS Transaction 연동 (NT) - 자바서비스넷  (0) 2008.07.03
Posted by marryjane
|

URLConnection 와 HTTPClient

java 2008. 7. 25. 17:50

* URLConnection
http://www.jabook.org/jabook/jabook07/10000_10000_50000__10000_10000_50000.html

* HTTPClient
http://programmers.tistory.com/entry/HTTPclient의-사용-1

* URLConnection 과 HTTPClient 비교
http://www.mimul.com/pebble/default/2007/06/09/1181399220000.html
 - 출처
 
URLConnection과 HTTPClient의 기능들을 비교하여 불필요한 라이브러리의 오용을 막을 수 있는 비교 자료를 제 피씨 백업하다가 찾았습니다. 죽어있던 지식이 블로그를 통해서 빛을 봤으면 합니다. ^^

 

URLConnection

HTTPClient

Methods

Only HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS.

Has HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS, plus any arbitrary method, such as those from WEBDav and IPP.

Response Codes

The response code, headers, and body can only be read if the response code was less than 400 - for any 4xx or 5xx response code, you only get IOException's when trying to get any response info.

The response code, all headers, and the body can always be read normally.

Proxies and SOCKS

Full support (SOCKS: Version 4 only)

Full support (SOCKS: both version 4 and 5)

Authorization

Support for Basic and an early version of Digest in JDK 1.2 or later, only. The current version of Digest authentication (which is the one supported by most servers) is not supported, and due to a bug of theirs they won't even recognize the digest info returned by Apache.

Support for Basic and Digest Authentication; other schemes can be added.

Cookies

No.

Yes.

True request output streams

No - all data is fully buffered before it is sent.

Yes - HttpOutputStream will stream directly to the socket.

True response input streams

Under JDK 1.2, yes; under JDK 1.3 only if the response is not sent using the chunked encoding (this excludes most server-push responses).

Yes.

Persistent Connections

HTTP/1.0 Keep-Alive's in JDK 1.1 and JDK 1.2; JDK 1.3 has HTTP/1.1 persistence.

Supports HTTP/1.0 Keep-Alive's and HTTP/1.1 persistence.

Pipelining of Requests

No.

Yes.

Can set Timeouts

No.

Yes.

Can handle protocols other than HTTP

Yes (e.g. ftp, gopher, mailto, and file are provided)

No.

Can do HTTP over SSL (https)

Appropriate SSL package (such as JSSE) which provides an appropriate client must be installed.

Patches are available for various free and commercial SSL packages

Source code available

No.

Yes.


'java' 카테고리의 다른 글

SI 프로젝트에서도 애자일 프로세스는 가능한가?  (0) 2008.07.28
HTTPClient 3.0  (0) 2008.07.25
javac 옵션  (0) 2008.07.09
IBM HOST CICS Transaction 연동 (NT) - 자바서비스넷  (0) 2008.07.03
jad 옵션  (0) 2008.06.05
Posted by marryjane
|