'분류 전체보기'에 해당되는 글 539건

  1. 2006.05.09 즐거워야 한다..
  2. 2006.02.19 AJAX BluePrints
  3. 2006.02.19 James Strachan on Java Business Integration
  4. 2006.02.19 Celtix ESB 진행현황 2
  5. 2006.02.12 글을 쓰는 습관과 연습 ... 1
  6. 2006.02.08 블로그 오픈 2
  7. 2006.02.08 Benchmark Report for JMS vs. Web Services 1
  8. 2006.02.02 웹서비스로 SOA 컴포넌트 구현하기
  9. 2006.02.02 # SOA(Service Oriented Architecture; 서비스 지향 아키텍처)
  10. 2006.02.02 [SOAㆍBPM] BPM<업무프로세스관리>
  11. 2006.02.02 SOA를 실현하는 ESB
  12. 2006.02.02 SOA(Service-oriented architecture)
  13. 2006.02.02 SOA 베스트 프랙티스: BPEL Cookbook
  14. 2006.02.01 ServiceMix와 Synapse의 차이점
  15. 2006.01.31 JavaEE 5, Spring 2 and AspectJ 5: dependecy injection magics
  16. 2005.12.16 ServiceMix as an enterprise service bus
  17. 2005.12.14 JBI &#8211; A Standard-based approach for SOA in Java
  18. 2005.10.26 Web Services + EA = SOA
  19. 2005.10.25 Java generics support in Eclipse V3.1
  20. 2005.10.16 Get a better handle on Struts actions, with Spring
  21. 2005.10.09 rownum, limit, top 요약
  22. 2005.10.09 Grouping(), ROLLUP, CUBE Study
  23. 2005.10.03 struts-config.xml 여러개 사용하기
  24. 2005.09.09 간단한 웹서비스/ebXML관련 표준 정리
  25. 2005.09.08 Why do developers need an Enterprise Service Bus?
  26. 2005.08.30 RTE 정리 잘된 곳
  27. 2005.08.29 실기간 기업을 위한 데이터 통합 1
  28. 2005.08.26 weblogic8.1에서의 JMS1.1사용 방법
  29. 2005.08.26 weblogic8.1는 기본적으로 JMS1.0.2b만 지원 1
  30. 2005.08.11 [JBoss] An Analysis of JBoss Architecture

즐거워야 한다..

2006. 5. 9. 10:08
뭐에 그리 쫓겼는지,
그리고 쫓으려 했는지 ...
막상 돌이켜보면 힘들었던 기억뿐 그다지 좋은 기억들이 아니였던거 같다.

예전의 즐겁게 공부하고 일하던 모습을 기억해내려하고 있다.
그렇다고 어렵게 고민하고 싶지는 않다. 이 역시도 스트레스고 즐거움을 빼앗아 가기에..

그냥 하고 싶은 것들을 하려한다.
너무 멀리 보지도 않으려 한다.
이젠 눈앞에 보이는 것부터 즐겁게 즐기고 싶다...
Posted by 아름프로

AJAX BluePrints

2006. 2. 19. 20:00
Java 에서의 AJAX는 J2EE 차원의 JSF와의 조화를 통해 전략적인 모습(!)을 찾아볼 수 있고,
이에 대한 자료로 볼 수 있는 것이 Sun의 AJAX BluePrints 이기에 시간날 때, 찬찬히 읽어볼 필요가 있을 듯 하다.

http://java.sun.com/blueprints/ajax.html
Posted by 아름프로
개인적으로 최근에 가장 좋아하면서.. 쫓아가고자하는 이가 James Strachan 이다.
관련 부분에 있어서의 방대한 량의 글과 댓글, 그에 대한 자부심과 또한 노력..
tss에서 인터뷰를 하는 모습에 멍하니... ~ 한동안 쳐다만 보았다는..

James Strachan on Java Business Integration

앞으로 나의 블로그로 통해서 많이 접하게 되리라 생각된다. ^^
Posted by 아름프로
Milestones
This page describes the breakdown and layout of Celtix targetted features across various milestones. The term complete means, finishing up the work of that specific feature based on the development plan proposed.

Current Milestone: Milestone 3

Milestone 1 - COMPLETE

   * Working end-to-end Hello World SOAP/HTTP scenario.
   * First cut of transport and binding API's
   * Minimal support for SOAP 1.1 and HTTP 1.1
   * Java-to-WSDL and WSDL-to-Java tools.

Milestone 2 - COMPLETE (November 1st, 2005)

   * Binding API design and implementation complete.
   * Handlers and Context Complete.
   * SOAP 1.1 support for Doc/Rpc literal and Faults Complete.
   * JAX-WS Sync and One-Way API's Complete.
   * Infrastructure ready for Tools.
   * Code re-organization and cleanup.
   * Complete Type Testing Framework.
   * Complete Design Note and Development Plan for WS-Addressing, Configuration and JMS transport.
   * Complete Design Note and Development Plan for JBI usecases.
   * Achieve Code Coverage to 75% especially for Milestone 2 deliverables.

Milestone 3 - COMPLETE (December 16th, 2005)

   * Complete Investigation of Jetty as potential HTTP Engine and Complete HTTP 1.1 and Servlet Transport support.
   * JMS Transport Complete (Pick one opensource JMS implementation to test)
   * SOAP 1.1 Headers Complete.
   * JAX-WS Async API's Complete.
   * WS-Addressing Complete
   * Exception & Error Handling
   * Configuration Infrastructure Complete.
   * Complete design note for WS-RM, JAX-RPC 1.1 and JMX.
   * Complete design note for Schema metadata work.

Milestone 4 - COMPLETE (Jan 31st, 2006)

   * Migrate Celtix to Maven 2.0 and Source Code Organization Complete.
   * WS-RM Infrastructure Complete.
   * Support for JAX-WS Dispatch and Provider API's Complete.
   * Non-Wrapper Doc/Literal Style.
   * Transport and Binding API's Complete.
   * WSDLToJava and JavaToWSDL Tools Complete.
   * Complete design note for Routing.
   * Complete design note for J2EE Integration. (Jonas and Geronimo).
   * Complete design note and Development plan for SCA and Celtix integration with Tuscany.

Milestone 5 (Tentative: March 31st, 2006)

   * JMX Work Complete.
   * WS-RM and enhanced WS-Addressing Work Complete.
   * Support for policy based configuration in JMS transport.
   * Tools Work Complete.
   * Routing work Complete.
   * XML Binding Support Complete.
   * XML Messaging API Complete.
   * Dynamic Configuration Support Complete.
   * J2EE Integration Complete.
   * First phase of JBI Integration Complete.
   * First Phase of SCA Integration Complete.
   * HTTPS and Basic Security Support.
   * Enhanced JAX-WS 2.0 Support.
   * Support for Schema Validation in Runtime

Milestone 6 and Further

   * JCA Support Complete.
   * Support for CORBA Binding and Transport.
   * Full SCA/Tuscany Integration.
   * Full JBI Integration.
   * STP Integration.
   * Certify JMS support with JORAM.
   * JAX-RPC 1.1 work Complete.
   * Support for SOAP 1.2.
   * WS-Policy Support.
   * Support for WSDL 2.0.
   * Metadata story complete.
   * Support for JSR 181 (Evolved from this discussion).
Posted by 아름프로
언제부터인가 혼자만의 독백이나 친한 사람들과의 커뮤니티 이외에는 글 쓰는 것을 잘안하게 되었던거 같다. 이유야 어찌되었던 그러한 것이 길어지다보니 예전의 많은 사람들과의 만남을 즐겨하고 함께하는 것을 좋아하던 내 자신의 성격도 혼자있는 것이 편하게되고 사람들에 대한 믿음이나 사람들 사귐에 있어서도 편한하게 대할 수 있는 이들이 아니고는 거리를 두게 되는 나 자신을 발견하게 된다.

이것이 비단 글을 쓰는 것 때문이 아님은 분명하지만,
이러한 것을 고쳐나가고 바꿔갈 수 있는 노력으로 글쓰는 것이 좋을꺼란 생각에는 확신을 가져본다. 어떠한 글을 올리고 커맨트를 달고 하면서 쓰고, 듣고하는 하는 활동에서부터 조금씩 혼자가 아닌 마음을 좀 더 열 수 있을 것 같기에...

좀 더 열심히!!

================================
개인적으로 사진을 찍는 것에  대한 재미와 의미를  알려준  오칠동의 '베로니카'님이
사진입니다. (일본에서 일하면서 틈틈히 살아가는 이야기들을 사진으로 들려주는..)
사진과 설명에서 처럼... 엉덩이 한대 맞고 '잠들어 있던 재능'을 눈뜨게 해야겠다는 생각에서 퍼와 봅니다.

(펌)엉덩이를 때려주는 이유는
" 엉덩이를 때림으로써, 추운 겨울내내 움츠렸던 몸을 피게 되듯이
액운을 물리치고 봄을 맞이한다. 또, 자신에게 잠들어 있던 재능을
눈 뜨게 하는 의미도 있다고 한다. "



















Posted by 아름프로

블로그 오픈

2006. 2. 8. 04:47
포탈형식의 사이트에서 블로그로 새롭게 변화시켜보았다.
이로써 5번째 사이트 변경이다.
또 어떤 변덕으로 사이트가 변경될지 모르겠지만,
개인적인 사이트는 블로그형태로 유지하며
포탈쪽에서는 tobearchitect.com(http://www.tobearchitect.com)
에 더 신경을 써야할 듯 싶다.

이번 사이트 변경과 함께 많은 것들이 지난 사이트에서 마이그레이션되지 않았지만, 즐겁고 새로운 마음으로 내용을 채워나가고자 한다. ^^
Posted by 아름프로

by Raghuram Bharadwaj C
07/20/2004

Objective

The objective of this benchmark is to compare the performance of JMS vs. Web services for sequential request processing.

Assumptions

  • Communication is synchronous (Client - Server)
  • Java clients are sending string messages to the server
  • Sequential Request Process -> stress test

Environment

The benchmark was tested under the following environment

  • Java Web Services Developer Pack/1.2, JVM Version 1.4.1-b21, Apache/Tomcat Web Server
  • MQ Series - Direct Connection, JDK 1.3.1/JDK1.4.1-b21
  • Windows 2000 Version 5.0 Service Pack 4 - 512 MB RAM
  • Windows 2000 Architecture - x86

1

1

1


Summary

The above results concluded that using Web services to connect to an external data source performs better than JMS under sequential request processing. If we go with JMS as an option, then MDB implementation would be a better choice.

Note: The benchmarking is done based on above architecture. Please do not compare it with the benchmarking results that are available on the Internet.

Other possible options for performing the benchmark are as follows:

  • Java clients sending XML messages to the server
  • Concurrent Request Process - Stress test
  • SOAP with attachments API

http://dev2dev.bea.com/pub/a/2004/07/jms_webservices.html

Posted by 아름프로

Brian Schaffner (ZDNet Korea)

이전 글에서 각 비즈니스 프로세스에 적합한 서비스 지향 아키텍처(SOA)를 구축하는 방법에 대해 논의한 바 있다. 이번 글에서는 SOA 아키텍처를 보다 세심하게 살펴보고 컴포넌트를 실행하는 방법에 대해 알아보자.


아울러 웹서비스 기술을 이용해 서비스 에이전시, 서비스 제공자, 그리고 서비스 요청자 등을 실행하기 위한 설계를 구축하는 방법 등에 대해 설명하도록 하겠다.

웹 기술로 서비스 실행하기
웹 기술은 상당히 풍부한 수준으로 서비스 실행 도구를 제공할 만큼 성숙해 왔다. 웹서비스 기술은 대체로 다른 기술을 기반으로 구축되며 특히 XMLHTTP에 근거를 두고 있다.

각 서비스들은 흔히 현존하는 애플리케이션을 포장한 형태로 제공되고 있다. 그림 A는 다양한 웹서비스 컴포넌트와 이들이 하나의 서비스 아키텍처를 수행하기 위해 어떻게 공조를 이루는지 그 연관 관계에 대해 설명하고 있다.


그림 A : SOA의 웹서비스 구현

위 그림에서 UDDI가 서비스 발견 에이전시를 제공하며 웹·애플리케이션 서버는 서비스 제공자를 전달하고 애플리케이션은 서비스 제공자의 역할을 하는 것을 발견할 수 있다. 이런 모습이 바로 SOA 모델의 충족 요건이 된다.

서비스 제공자에서 애플리케이션 기능성 요약하기
웹 서비스는 하나 또는 그 이상의 애플리케이션 전반에 걸쳐 실행된다는 기능성을 갖춘 서비스의 ‘포장’을 반드시 제공해야 한다. 일부 웹서비스는 아마 다른 웹서비스들이 다중 애플리케이션에 대한 통합 인터페이스를 제공하는 반면에 단일 애플리케이션을 대상으로 한 기능성을 제공하고 있는지도 모른다.

애플리케이션을 서비스 측면에서 면밀히 계획해 보면 애플리케이션과 기술이 비즈니스 프로세스에 적합한지 살펴볼 수 있다. 그림 B는 애플리케이션의 기능성이 서비스 실행으로 면밀하게 계획되는 방법에 대한 사례를 보여준다.


그림 B : 애플리케이션 기능성이 서비스에 매핑되는 예

EJB와 같은 컴포넌트 아키텍처는 애플리케이션 서버 환경에서 수행될 수 있는 서비스를 요약해 보여준다.

웹 서버는 서비스 접근에 대해 HTTP 네트워크 전송 방법을 제시하며 애플리케이션 서버는 SOAP 인터페이스와 서비스를 구성하는 객체 컴포넌트를 주관한다. 객체 컴포넌트는 애플리케이션들에 대해 비즈니스 서비스 계층을 제공한다.

결과적으로 웹서비스는 기초적인 애플리케이션들에서 풍부하게 정의된 서비스들을 이끌어 낸다. 이러한 서비스는 이후 개념 정의가 잘 된 비즈니스 프로세스로 연결된다.

애플리케이션 전반에 걸친 개념적 계층을 구성하면 각 애플리케이션의 기능성을 비즈니스 서비스로 정의된, 보다 의미 있는 방법으로 전달할 수 있다.

WDSL 환경의 서비스 규약 정의
서비스 제공자는 WSDL 문서 형태로 해당 인터페이스 규약을 출판한다. WSDL 문서는 서비스 위치 지정, 그리고 해당 서비스에 대한 접근 방법까지 포함하는 서비스의 특징을 정의한다. 개발적 관점에서 볼 때 WSDL은 서비스 요청자와 서비스 공급자가 모두 동의하는 규약을 제공한다.

일단 비즈니스 프로세스를 정의하고 해당 프로세스를 실행할 서비스를 조직하고 나면 그 다음 단계는 서비스와 서비스 내부의 특정 방법론을 결정하는 것이다.

WSDL은 세부 서비스의 XML 포맷이다. WSDL 문서 내에서 서비스 접근법, 가능한 방법에 대한 판단, 방법에 대한 접근, 방법까지 나아가는 동안 거쳐야 하는 매개변수, 기타 여러 요소에 대한 세부 작업을 수행할 수 있다.

서비스 요청자들은 서비스 레지스트리를 이용해 서비스를 위치시킨다. 웹서비스의 실행에서 서비스 레지스트리는 UDDI를 이용해 실행된다. UDDI 서버는 서비스 내역에 대한 데이터베이스를 갖고 있으며 이들을 서비스 요청 애플리케이션에 제공한다.

서비스 요청자는 웹서비스와의 인터페이스 규약을 납득하기 위해 WSDL 문서를 활용한다.

일반적으로 WSDL 문서는 물리적으로 UDDI 서버에 저장되는 것은 아니다. 오히려 UDDI 서버는 서비스 요청자에게 WSDL 문서를 어디서 발견할 수 있는지 위치를 확인할 수 있는 URL들을 제공한다.

프로그래머의 측면에서 WSDL 문서는 서비스에 접속하기 위해 사용하는 개념 인터페이스를 정의한다. 설계 측면에서 WSDL은 서비스 요청자와 제공자 사이의 규약을 규정하기 때문에 반드시 이 2가지 앞에 위치해야 한다.

일단 WSDL이 설계돼 합의되면 서비스 제공자의 개발자와 서비스 요청자의 개발자는 다소 평행적으로 작업하게 된다.

서비스 발견
서비스는 UDDI 서버에 질의하고 관련된 WSDL 문서에 접근함으로써 발견된다. 중심 레지스트리를 사용함으로써 클라이언트 애플리케이션은 역동적으로 서비스를 발견하고 이에 결합될 수 있다.

UDDI 서버 및 프로토콜은 상당히 포괄적이다. 하나의 서비스 아키텍처로서 UDDI 컴포넌트는 자신의 도메인 내에 위치한 모든 서비스에 대해 잘 알고 있는 중앙 에이전시 역할을 수행한다. 언제든 서비스 요청자가 서비스에 접근하거나 서비스를 위치시켜야 할 때마다 UDDI 서버는 정보 요청을 받는다.

UDDI는 레지스트리를 검색하는데 있어 다양한 방법을 제공한다. 일단 하나의 조직과 서비스가 위치되고 나면 서비스 요청자는 WSDL 위치를 요약한다.

WSDL 은 대개 서비스 그 자체와 함께 위치한다. 그 다음 서비스 요청자는 서비스의 세부 사항을 알기 위해 WSDL 문서에 접근한다. WSDL 문서 내의 정보를 활용해 서비스 요청자는 서비스에 접근하는 방법, 그리고 어떤 방법론이 있는지, 어떤 매개변수가 보내져야만 하는지 등을 다른 것보다 먼저 이해하게 된다.

그림 C는 이러한 프로세스가 작동하는 것을 묘사한 것이다.

그림 C : 서비스 요청자로부터 WSDL에 접근하기

향후 과제
SOA를 구현하는 것은 정말 하나의 도전과도 같다. 구현을 통해 SOA를 구성하는 컴포넌트와 웹서비스 이면의 기술들을 이해함으로써 풍부한 전략적 솔루션을 제공함과 동시에 각 비즈니스의 필요 부분과 도전과제 등을 충족시키는 실속있는 아키텍처를 만들어 낼 수 있을 것이다.

Posted by 아름프로

떠돌아다니는 내용인데.. 괜찮은거 같아서.. 퍼봅니다.
=============================================

# SOA(Service Oriented Architecture; 서비스 지향 아키텍처)

연재 가이드

기본 배경 - J2EE 5.0
J2EE 1.4가 나온 지도 이제 1년이 지났고 예정대로라면 올해 하반기에 위용을 드러낼 J2EE 5.0(J2SE 5.0처럼 1.5가 아닌 5.0으로 버전이 고쳐졌다)을 벌써부터 다루는 것이 무척 성급하게 비칠 수도 있지만 이미 필자가 작년 11월에 J2EE 5.0의 핵심 기술 중 하나인 JBoss의 EJB 3.0 조기 구현체로 과제를 무사히 마쳤을 정도로 상황이 빠르게 진행되고 있다. 웹 쪽은 JSP 2.1, JSTL 1.1, 그리고 JSF 1.2로 EL 공유와 통합이 한창이고, 웹 서비스도 J2EE 1.4에서 보여준 초기적 기술 상태를 벗어나기 위해 JAX-RPC 2.0과 JAXB 2.0, 그리고 WSM(Web Services Metadata) 1.1로 재무장되어 가고 있다.

JBoss가 자신들의 AOP 프레임워크와 하이버네이트를 결합하여 EJB 3.0의 조기 구현체

웹 서비스 개발에서도 누누이 강조하는 개념 중의 하나로 coarse-grained가 있다. 필자가 처음 이 용어의 번역을 시도했을 때(O'Reilly의 Java Web Services, 2002년), 오로지 생각하는 것이라고는 스타벅스에서 원두를 샀을 때 “어떻게 갈아드릴까요?”라는 질문에 “굵게 갈아주세요”하는 바로 그 ‘굵게 갈음(coarse-grained)’이었다. 웹 서비스에서는 반대말인 fine-grained를 하지 말라는 뜻이기도 한데 도대체 뭘 잘게 갈지 말고 굵게 갈라는 뜻일까?

대답은 의외로 간단하다. 사용자가 사용할 인터페이스에 개발자의 잣대를 들이대지 말라는 말이다. 사용자는 장소와 시간을 주고 예약 가능한 택시 목록을 보고 싶다. 개발자는 ‘음··· 일단 xx1 메쏘드를 호출하는 식으로 장소와 시간을 받아온 뒤 xx2 메쏘드를 불러 DB 연결을 얻어 온 후 xx3 메쏘드로 사용자 인증을 한 후 xx4에서 장소를 정규화하고···’ 이렇게 머릿속에는 이미 아스트랄한 메쏘드 세상이 펼쳐지는 것도 모자라서 ‘이렇게 해놓으면 나중에 또 쓸 수 있겠지?’하며 흐믓한 미소마저 짓는다. 재사용을 위한다면 메쏘드를 public으로 할 것이고, 이러다 보면 메쏘드의 공개는 파죽지세로 이어진다.

이러한 public 메쏘드와는 별도로 공개된(published) 메쏘드라는 개념이 나와 관심을 끈다. 물론 공개된 메쏘드는 자바 문법으로는 나타낼 수 없지만 단순히 접근 수준을 정하는 정도가 아니라 이 메쏘드를 외부의 클라이언트가 호출할 수 있게 하겠느냐는 뜻에서 공개되었다는 표현을 쓴 것이다(Erich Gamma와 Kent Beck이 쓴 『Contributing to Eclipse』에서 발췌). WSM에서는 공개된 메쏘드에 대한 표식을 가능하게 하는 메타데이터가 제공되고 있으니 정리하면 사용자에게 쓰도록 내비칠 오퍼레이션(웹 서비스에서는 메쏘드라는 프로그래밍 언어적 용어 대신 오퍼레이션을 대응하여 쓴다)은 최대한 굵게, 그리고 프로그래밍 언어의 public과는 차별화해야함이 coarse-grained의 현실적 취지이다.

Posted by 아름프로


기업 ‘중장기 혁신’ 핵심화두로


전사적자원관리(ERP) 기반 프로세스혁신(PI) 활동의 한계에 대한 지적과 함께 지속적인 경영혁신에 대한 관심이 이어지면서 새해에도 업무프로세스관리(BPM) 시장은 엔터프라이즈컴퓨팅 업계의 핵심화두로 꼽히고 있다.


BPM 이란 프로세스 정의에서부터 분석, 실행, 모니터링, 관리 등을 포함하는 프로세스 경영을 위한 제반 서비스 및 관련도구를 지칭하는 것이라고 할 수 있다. 기업 내 임직원과 애플리케이션 시스템, 업무파트너 등을 효과적으로 통합할 수 있도록 여러 업무활동을 설계하고, 실행하며, 최적화하는 관리기법을 의미한다.


지 금까지 ERP가 기업의 핵심 업무프로세스를 대상으로 업무를 개선하고 자동화하는 데 초점을 맞췄다면 BPM은 ERP에서 포괄하지 못하는 프로세스를 포함해 전사 업무프로세스를 대상으로 지속적으로 개선활동을 추진할 수 있는 기법이라는 점에서 주목받고 있다.


◇2005 년 BPM 확산 원년=지난해는 국내 BPM 시장이 도입기를 지나 본격적인 확산기로 접어드는 원년이었다고 평가할 수 있다. 대기업, 금융기관, 공공기관 등 산업과 기업의 규모를 불문하고 BPM에 대한 관심이 높았다고 해도 과언이 아니다. 또 대부분의 기업�기관들은 BPM을 한두 번의 프로젝트가 아닌 향후 기업의 중장기 혁신활동을 위한 핵심화두로 인식하는 분위기다.


지난해 국내 BPM 도입 움직임은 크게 3가지 부류로 나뉠 수 있다.


먼 저 민원서비스, 연구개발, 은행의 프론트엔드 업무프로세스재설계(BPR) 등을 대상으로 BPM 기반의 부문별 애플리케이션을 구축하는 움직임이다. 소위 `업무를 BPM에 태운다'는 표현으로, 협의의 BPM시스템을 구현하는 것을 의미한다.

또 하나는 BPM 기법을 이용해 전사 업무프로세스를 정의하고, 표준화는 시도다. GS홈쇼핑의 `프로세스최적화 프로젝트'(POP)와 포스코의 SOP(Standard Operation Procedure) 프로젝트, CJ의 포스트PI 프로젝트가 대표적인 예다. 이들 프로젝트는 기존 ERP 프로세스는 물론 ERP가 포괄하지 못하는 전사 모든 프로세스를 대상으로 계층별 프로세스 표준화 작업을 수행하는 것이 핵심 과제. 주된 내용은 향후 지속적인 개선활동을 위해 모든 프로세스와 프로세스간 관계에 대해 시각화하는 것이다.


마 지막으로 지난 한해 BPM 프로젝트와 관련해 가장 많은 관심을 모은 LG전자의 사례와 같은 경우다. LG전자는 전사 프로세스의 표준화 작업과 함께 단위 업무별로 BPM시스템을 구축하는 작업을 진행함으로써, 앞서 언급한 2가지 유형을 모두 구현하는 사례다.



◇올 BPM 시장 전망=올해 국내 BPM 시장은 이 3가지 유형이 본격적으로 확산되면서 대기업 프로젝트의 경우 LG전자와 같은 사례로 점차 수렴하는 양상을 보일 것으로 전망된다.


어차피 단위 업무프로세스를 최적화하는 것이 목표가 아니라면 전사 프로세스의 표준화 이후 BPM시스템을 구현하는 작업이 필요하기 때문이다.


이 에 따라 BPM 솔루션 시장도 기존 BPM시스템을 구축할 수 있는 워크플로 자동화 중심의 시장이 지속적으로 확대되는 가운데 프로세스를 설계하고 리포지토리를 구축할 수 있는 프로세스 모델링 툴 시장이 본격적으로 개화할 것으로 예상된다.


국내 BPM 시장은 BPM 기반의 애플리케이션을 구축할 수 있는 BPM시스템용 툴 시장과 프로세스모델링 툴 시장 등 2가지 부문으로 크게 나눌 수 있다.


먼 저 BPM시스템용 툴 시장은 은행 등의 BPR 수요와 공공기관, 대기업 등의 특정업무 최적화를 위한 시도가 본격화되면서 올해에도 빠르게 확산될 것으로 예상된다. 올해 이 시장은 한국파일네트, 스태프웨어, 새비온(나라정보기술 공급) 등 외산 솔루션 업체와 핸디소프트, 리얼웹 등 국산 소프트웨어 업체가 치열한 경쟁을 벌일 것으로 보인다. 지난해의 경우 핸디소프트, 리얼웹, 한국파일네트 등이 시장에서 두각을 나타냈다.


프 로세스모델링 툴 시장은 전통적인 BPM시스템용 툴 업체간 경쟁과는 다른 양상으로 경쟁이 펼쳐지고 있다. 이 시장은 지난해 모델링 툴을 처음 선보인 핸디소프트를 비롯해 이 시장에서 강점을 지니고 있는 리얼웹 등 전통적인 BPM 업체와 IDS쉬어, 코퍼리트모델러 등 외산 모델링 툴 전문업체간의 경쟁으로 치닫고 있다.


최 근 BPM은 균형성과표(BSC)기반의 성과관리, 6시그마 혁신활동 등과 결합되는 양상을 보이고 있다. 또 기술적인 측면에서는 서비스지향아키텍처(SOA), 업무규칙엔진(BRE) 등 다양한 신기술과 접목해 그 효과를 높이기 위한 시도도 잇따를 것으로 보인다. 지난해 하반기 아주그룹이 BPM 기반 6시그마과제관리 프로젝트를 시작한 것이 대표적인 예다.


이밖에도 올해에는 BPM 기술과 접목할 수 있는 업무활동모니터링(BAM) 등 다양한 기술과 접목하려는 시도도 잇따를 것으로 보인다. BAM 시장은 지난해 개념 소개와 함께 올해 첫 구축사례가 나올 것으로 업계에서는 기대하고 있다.


이처럼 새로운 영역이나 기술과 BPM 개념을 적용하려는 시도가 잇따르면서 올해 국내 BPM 시장은 관련 솔루션 업체간 경쟁이 그 어느 때보다 치열한 한 해가 될 전망이다.


박서기기자@디지털타임스

Posted by 아름프로

SOA를 실현하는 ESB

SW와 애플리케이션간의 연동을 위한 미들웨어 플랫폼


임철홍|SK C&C R&D센터 기술전략팀 과장

ESB(Enterprise Service Bus)는 웹서비스(Web Service), 인텔리전스 라우팅(Intelligent routing), 트랜스포메이션(Transformation) 기술을 기반으로 SOA(Service Oriented Architecture)를 지원하는 미들웨어 플랫폼이다. ESB는 SW 서비스와 애플리케이션 컴포넌트간의 연동을 위해 경향화된 백본의 역할을 수행한다. ESB를 통해 분산된 서비스 컴포넌트를 쉽게 통합 연동이 가능하며, 신뢰성 있는 메시지 통신이 가능하다.


ESB를 통한 서비스 컴포넌트로는 웹서비스 컴포넌트뿐만 아니라 어댑터(Adap-ter) 기술을 활용한 ERP 등의 레거시 컴포넌트, B2B 컴포넌트, J2EE & .NET 컴포넌트가 있다. ESB는 Emerging Technology로써 가트너에 따르면 올해 가장 관심 높은 기술로써 보고되기도 했다.


ESB의 유형으로는 MQ방식과 Proxy 방식으로 나눌 수 있다. MQ방식은 EAI를 확장하여 메시지의 통로로써 역할을 수행하며, 자체 또는 외부의 프로세스 관리 기능을 활용하는 미들웨어 플랫폼이다. Proxy 방식의 ESB는 기본적인 메시지 라우팅 기능을 기반으로 개별적인 웹서비스를 중앙의 Proxy를 통해서 관리가 가능하도록 지원하는 플랫폼이다.

두 가지 방식의 차이는 해당 플랫폼의 활용 측면에서 차이가 난다. MQ 방식은 EAI 측면의 BPM 구축 시에 유용하며, Proxy 방식은 웹서비스 관리 솔루션에서 도입 활용되고 있다. 초기의 ESB의 시작은 MQ 방식의 ESB에서 시작되었으며, 최근에 웹서비스 관리 솔루션의 등장과 함께 Proxy 방식의 ESB에 대한 관심이 높아지고 있다.

SOA에서의 ESB 역할

분산된 서비스 컴포넌트의 효율적인 통합을 위해서 ESB는 BPEL 혹은 솔루션 벤더의 자체적인 표준을 따르는 프로세스 매니저와 연동해 프로세스 기반의 통합을 지원한다. 기능적으로는 기존의 EAI와 같은 역할을 수행하며, 프로세스 기반의 통합 지원과 웹서비스 기반의 통합환경 등을 지원한다.



1. Service Component Integration

XML 기반의 동기/비동기 SOAP 메시징: SOAP 표준에 기반한 메시지를 교환함으로써 이기종/분산 환경에서의 데이터 및 애플리케이션 연동이 가능하게 지원함. 궁극적으로 프로세스 연동을 지향함


Secure and reliable messaging: MQ와 같은 MOM(Message Oriented Middleware)을 활용하여 메시지 전송의 안정성과 보안성을 지원함

Intelligent routing and inter-mediaries: 메시지의 내용에 기반한 라우팅을 지원하고 메시지를 중개함
Data transforming: XSLT, XQuery를 통한 데이터의 변환을 지원
QoS: 정해진 시간에 일정한 메시지 전송 수를 보장되도록 조정하는 역할
Legacy 통합: DB, ERP와 같은 자원과의 통합을 위한 어댑터를 제공하며, 어댑터를 통해서 애플리케이션 레벨의 통합이 가능하도록 지원

2. Support SOA

웹서비스 지원: 웹서비스 클라이언트 역할 수행이 가능하도록 자동화된 기능(WSDL 지원, 메시지 처리)을 제공한다.
프로세스 지원: 처리할 서비스 단위의 업무 처리를 제어할 수 있는 프로세스를 정의하고, 프로세스 기반 하에서 업무 처리가 가능하다.
메시지 표준: XML 기반의 표준화된 메시지 기반(주로 SOAP)으로 통신이 이루어진다. 경우에 따라서 ESB 내부적으로는 자체 표준으로 변환하여 사용하지만, ESB 외부로는 SOAP을 표준으로 사용한다.

3. Advanced Integration

Work List: 사용자의 입력 또는 승인 처리를 지원하기 위한 비동기적(Asynchronous)인 입력 방식을 지원하여, 사용자의 입력을 기다리고, 사용자의 입력에 따른 처리를 진행할 수 있도록 지원

B2B 프로토콜 지원: RossetaNet, ebXML과 같은 B2B 프로토콜을 지원하여, 글로벌한 전자상거래를 지원

4. Composite Component

여러 서비스와 연동되어 있는 ESB는 자체적으로 컴포넌트의 형태로 구성이 되며, 여러 단위 서비스가 프로세스 형태로 연결되어 있는 복합 서비스로 활용 가능하다.

개 별적인 컴포넌트를 기반으로 ‘Composite Component’로 구축되는 SOA 아키텍처의 모습은 다음과 같다. Atomic Service는 단위의 Service Component를 나타내고 있으며, ESB 기반 서비스 형태의 Composite Compo-nent를 구성하게 된다. 개별 애플리케이션은 이들 Composite Component를 사용하여 동작하게 되며, 결과적으로 프로세스 기반의 통합을 지원하는 형태가 된다.




ESB의 특징

SOA를 지원하기 위하여, ESB는 몇 가지 차별적인 특징을 가지고 있다. 메시지 기반의 Loosely Couple한 표준 인터페이스 기반의 통신을 지원하고 있으며, 표준적인 메시지 표준인 SOAP을 지원한다. 또한 BPM 기반에서 프로세스 레벨의 통합이 가능하도록 지원되고 있다.


Loosely coupled: 표준 인터페이스(WSDL)를 준수하는 메시지 전송에 의해서 애플리케이션간의 연관성이 적은 형태에서 연동을 지원
Highly distributed integration network: beyond hub-and-spoke EAI broker, centralizes control and distributes processing
Event-driven: 독립적인 애플리케이션에 의한 프로세스의 시작이나 정지, 재시작 등의 조정이 가능한 형태
Documents-oriented(Message Driven)
Support for several standard interfaces: From a list including COM, CICS, .NET, JMS, JCA, JDBC, and Web Services - Broker를 중심으로 Legacy, Middleware, Database 간의 연동을 지원

ESB Architecture

1. Process

사용자가 정의한 Activity(Service) 단위로 수행이 가능하도록 수행 순서를 정의하고, 경우에 따라서 조건에 따른 콘텐츠 기반 라우팅이 가능하도록 지원한다. 메인 프로세스에 종속되는 서브 프로세스를 가질 수 있으며, 프로세스의 시작과 종료 시점까지 ESB를 통해서 실행이 진행되게 된다. ESB 내부에 프로세스 매니저가 존재하기도 하며, 별도의 프로세스 매니저(BPM)를 활용할 수도 있다.

2. Service(Service Component)

프로세스 상에서 진행되는 모든 Activity를 서비스로 지칭할 수 있다. 서비스는 자체적으로 처리를 진행하거나(메시지 변환 등) 외부의 서비스 컴포넌트를 호출해 처리가 가능하다. 외부의 서비스 컴포넌트를 호출하여 처리하는 경우 ESB 내부의 서비스는 클라이언트의 역할을 수행한다.

3. Adapter

레거시를 연동하거나 특정한 애플리케이션과의 통합이 필요한 경우 이를 가능하게 하는 역할을 수행한다. 주로 레거시 애플리케이션을 통합하는 경우에 사용하며, 메시지의 생성과 변환을 통해서 중계하는 역할을 수행한다.

4. Messaging Layer

메시지가 신뢰성을 보장하면서 전송 되도록 지원하며, 메시지가 올바른 목적지에 전달 가능하도록 라우팅 기능을 제공. 메시지 전송 시에 Failure나 Reject와 같은 경우 재전송 및 처리가 가능하도록 특정 장소에 저장하여 보존한다. WS-Reli-ability 표준을 통한 신뢰성 보장이 목적이다.

ESB Integrated Architecture

ESB의 목적은 자원을 부서별/업무별로 분산하여 처리가 가능하도록 분산 아키텍처를 지원하고 있다. 동일한 솔루션 ESB를 활용할 경우 통합처리 및 관리에 문제가 없으나, 이기종 간의 ESB를 통합 활용하게 될 경우 대부분의 ESB가 지원하는 웹서비스를 활용하여, 프로세스의 처리가 가능하지만, 솔루션의 차이에 따른 다음과 같은 문제점이 발생하게 된다.


연동되는 ESB안에 Asynchronous한 Component가 있을 경우 즉시적인 응답을 얻을 수가 없기 때문에 Call-Back URL을 활용하여 향후 결과를 반영 할 수 있다.
통합 모니터링이 지원되지 않으므로, 전체적인 프로세스 관리가 어렵다. 즉 프로세스의 실행에 따른 결과 트래킹이 어렵다.
하나의 프로세스를 다른 프로세스로의 이식이 어렵다. BPEL 표준을 활용하는 솔루션의 경우에도 표준 외에 부가적으로 사용하는 기능 때문에 호환성 문제가 발생 할 수 있다.


BPM에서의 ESB활용 방안

ESB는 자체 내장된 프로세스 매니저를 활용하거나 또는 외부의 프로세스 매니저와 함께 사용되어, BPM의 역할을 수행할 수 있으며, 이때 EAI형태의 BPM 솔루션과 같은 역할 수행이 가능하다. 거대 단위의 업무 기반에서 BPM 적용 시에 상위 비즈니스 프로세스를 주로 담당하는 상위 프로세스와 시스템 및 서비스 통합을 주로 담당하는 하위 프로세스를 나누어 계층화하여 구축하면 효율적인 BPM 구축이 가능하다.

상위 프로세스 상에서 서비스 통합을 담당하는 하위 프로세스로 구성된 개별 Composite Component를 활용하는 형태이다. 상위 프로세스를 위한 워크플로우 형태의 BPM 솔루션과 시스템 및 서비스 통합에 해당하는 하위 프로세스를 처리하는 ESB 솔루션과 연동하여 전체적인 프로세스를 지원하는 효율적인 BPM 구축이 가능하다.

ESB를 활용하여 SOA 기반의 시스템 구축이 활성화되기에는 여러 비즈니스, 테크놀로지 측면의 이슈 사항이 존재한다. 이러한 이슈 사항을 해결하기 위해서 많은 노력이 진행 중이지만, 궁극적으로는 정보시스템 환경인 인프라와 기업의 업무 형태가 획기적으로 바뀌어야 하므로 시간이 소요 될 것으로 전망된다.

SOA의 가치를 충분하게 보장할 수 있도록 시스템을 구축하기 위해서는 ESB를 활용한 아키텍처 구성 및 구축이 필수적이며, 이를 위한 솔루션의 검증 및 정보시스템 환경과 업무 요구사항에 알맞은 솔루션을 채택하고 그에 맞도록 아키텍처 구성을 필요로 한다. 기존의 정보 자원과 요구사항에 맞는 신규 자원의 구축 및 전체적인 프로세스 레벨의 통합을 통해서 SOA가 구성 될 수 있으며, 이를 위한 ESB의 역할이 점차 확대될 것이다.

현재의 ESB 솔루션은 계속해서 진화 발전하고 있으며, 서비스 컴포넌트의 확산과 함께 본격적으로 도입 및 활용될 것으로 전망된다.


제공 : DB포탈사이트 DBguide.net



출처 : 경영과컴퓨터 [2005년 12월]
Posted by 아름프로
SOA(Service-oriented architecture)

SOA(Service-oriented architecture)란 무엇인가?

서 비스 지향 아키텍처는 기업이 내부 애플리케이션을 기업 내·외부까지 통합할 수 있는 표준 소프트웨어 요소이자 비즈니스 프로세스의 집합체이다. 예를 들어 알파벳에서 하나하나의 문자들을 서비스로 본다면, SOA는 이 문자들을 활용해서 문장이나 글로 써나가는 규칙을 설명하는 문법책이라고 볼 수 있다. 또한 레고 블록 하나 하나를 서비스로 본다면, SOA는 이들 블록을 사용하여 건물이나 자동차 등을 만들 수 있는 방향과 지침을 제시하는 것으로 비유할 수 있다. 따라서 IT 측면에서 볼 때 SOA는 기업 IT 자원간의 궁극적인 상호 호환성을 제공하기 위한 차세대 통합 개념이라고 할 수 있다.
SOA는 데이터와 애플리케이션을 표준 블록 단위로 나눠 하나의 서비스로 구성한 뒤 웹서비스 기술 등을 적용해 각 서비스를 조합 또는 재사용할 수 있게 한다. 내부 애플리케이션과 서비스를 통합하는 것은 물론이고 협력사·하도급업체 등의 외부 시스템까지 연계할 수 있다.

일례로 모 기업은 전사적자원관리(ERP)를 비롯한 주요 엔터프라이즈 애플리케이션으로 상이한 2개 업체 제품을 사용하고 있다. 게다가 고객과 제품·직원 및 파트너에 관한 엔터프라이즈 데이터베이스도 운영하면서 문서와 콘텐츠관리서비스·구글의 서치 서비스 등도 운영 중이다.

이처럼 분산된 정보시스템 인프라를 가지고 있는 사용자가 쉽게 서비스 받을 수 있는 환경을 만드는 것이 SOA의 기본 이념이다. 즉 시스템을 누구나 이용 가능한 서비스로 간주하고 연동과 통합을 전제로 아키텍처를 만든다는 것이다.

SOA는 컴퓨팅 환경 내에서 분산된 로직(서비스)을 유연하게 디자인·개발·배치·관리하기 위한 소프트웨어 인프라 시스템 패러다임이다. 이 정의는 SOA의 전반적인 범위를 표현한다.

SOA의 원리

SOA는 비즈니스 기능들을 네트워크 상에서 재사용이 가능한 공유서비스의 집합으로 구현한 소프트웨어 디자인 패러다임이다. Burton Group의 부사장이자 연구 책임자인 Anne Thomas Manes는 ‘웹서비스는 표준 메시지 포맷과 프로토콜을 사용하는 서비스 중심의 통합 기술’이라고 말했다.

한 덩어리의 방대한 코드로 이루어진 애플리케이션들을 각각 개발하는 대신 SOA를 디자인 패턴으로 채택하면 각각의 비즈니스 기능들로 이루어진 유연한 인프라를 구축할 수 있다. 즉 이 비즈니스 기능들을 조합하거나 분리함으로써 유연하면서도 상세하게 모든 비즈니스 프로세스들을 구현할 수 있게 되면서 급변하는 환경에 맞춰 신속하게 비즈니스 프로세스들을 수정할 수 있다.

그래서 SOA는 웹서비스 표준 지원, 기존 투자된 애플리케이션 인프라를 활용하기 위한 전사 애플리케이션 통합 하부구조, 비즈니스 프로세스를 자동화하고 애플리케이션간 비즈니스 프로세스 상호 교환을 위한 서비스 오케스트레이션, XML·non-XML·객체 등 다양한 유형별 데이터 통합 및 맵핑, 기존 컴포넌트 시스템 통합, 서비스 개발 환경을 위한 개발 도구 등을 요건으로 하고 있다.

SOA는 여러 시스템에서 애플리케이션 기능을 재사용할 수 있도록 함으로써 애플리케이션 개발과 통합 작업을 간소화할 것이다. 물론 이전의 컴포넌트 기반 아키텍처에서도 이런 시도는 있었다. SOA와 컴포넌트 기반 아키텍처의 근본적인 차이점은 SOA는 주로 표준 기반의 웹서비스에 의존하고 있기 때문에 기반 기술로서 그 어떤 것도 필요로 하지 않는다는 점이다.

도입 필요성

가트너 그룹은 ‘2008년에는 60% 이상의 기업이 회사의 핵심 애플리케이션과 프로세스를 개발할 때 SOA를 소프트웨어 개발 원칙으로 사용할 것’이라고 밝혔다. 또한 웹서비스 컨설팅전문회사 잽 씽크(ZapThink)는 ‘오는 2006년까지 네트워크화된 비즈니스 시스템에서 SOA가 지배적인 디자인이 될 것’이라고 예상하고 있다.

SOA를 적용하면 기존에 힘들게 애플리케이션 코드를 프로그래밍하던 방식에서 탈피, 애플리케이션 전체나 일부가 서비스 개념으로 인식되어 쉬운 조립(assembly)을 통해 새로운 비즈니스 애플리케이션을 빠르게 개발할 수 있다. 이를 통해 현업부서가 쉽게 업무를 재구축할 수 있도록 해주면서 기존 IT부서 중심의 컴퓨팅 환경은 비즈니스 중심으로 바뀌어 더욱 신속히 비즈니스 요구를 반영할 수 있다.

SOA 도입에 따른 혜택


- 탄력성의 증가로 인한 컴퓨팅 시스템 변경시 매우 유리
- 대규모 시스템이거나 원거리 협력 작업 용이
- 모듈의 재구성 가능에 따른 소프트웨어의 재사용 가능
- 이기종 환경의 통합
- 통합이 쉬워지고 민첩성이 높아지므로 ROI 높아짐
- 개발자들은 모든 종류의 사용자 접점 시스템과 작동하기에 충분할 만한 일반적인 서비스 디자인 가능
Posted by 아름프로

SOA 베스트 프랙티스: BPEL Cookbook

실제 애플리케이션 개발 경험을 보유한 설계 전문가들로부터 개발, 구축, 운영에 관련한 고급 BPEL 개념과 베스트 프랙티스를 배워 봅시다.


기존 애플리케이션을 컴포지트 애플리케이션(composite application)으로 통합하기 위한 보다 개방적이고 유연한 대안으로 SOA(service-oriented architecture)가 각광받고 있습니다. SOA의 구현 작업은 크게 두 단계로 나뉘어집니다. 먼저, 기존 애플리케이션을 재활용 가능한 서비스로 분할해야 합니다. 두 번째로, 이 서비스들을 유연한 비즈니스 프로세스 내에 “통합(orchestrate)”해야 합니다.

업계의 SOA 구현 노력을 지원하기 위한 목적에서, OTN은 SOA 및 BPEL 분야의 전문가들이 집필진으로 참여하는 새로운 시리즈 “SOA 베스트 프랙티스: BPEL Cookbook”을 기획하였습니다. 비즈니스 룰의 관리, BPEL 프로세스의 다이내믹한 생성, BPEL과 고전적 EAI 미들웨어의 통합 등을 주제로, 필자들이 실제 IT 환경에서 BPEL을 성공적으로 적용할 수 있었던 비결을 알려 드리게 될 것입니다.

이 연재에 관련한 의견 및 질문은 BPEL 사용자 포럼에 올려 주시기 바랍니다. BPEL에 관련한 개인적인 경험을 OTN 커뮤니티에서 공유하고자 하는 경우에도, 포럼을 통해 의견을 전달해 주시면 감사하겠습니다.
Oracle BPEL Process Manager를 직접 테스트해 보고자 하시는 경우, 제품 다운로드 페이지를 참고하시기 바랍니다. (15분 안에 설치를 완료하실 수 있습니다!)


Edwin Khodabakchian, VP, BPEL Development
Dave Shaffer, Director Product Management, Oracle BPEL Process Manager
Harish Gaur, Principal Product Manager and "BPEL Cookbook" Editor
Markus Zirn, Director, Strategic Customer Program


촐시된 아티클 *
Kevin Geminiuc제 1부 : 비즈니스 룰 개발을 위한 서비스 지향적 접근법
비즈니스 룰 개발 및 관리를 위한 서비스 지향적 접근법을 통해 유지보수 비용을 절감하고 조직의 유연성을 개선하는 방법을 배워 봅니다.
저자 - Kevin Geminiuc, Senior Software Architect, Policy Studies Inc.
Yves Coene제 2 부: BPEL을 이용한 웹 서비스 네트워크의 구축
European Space Agency가 BPEL 스코프, BPEL 도메인, Oracle BPEL Process Manager API 등을 이용하여 파트너 친화적인 웹 서비스 네트워크를 구축한 사례를 소개합니다.
저자 - Yves Coene, Project Manager, Spacebel s.a.
Sean Carey제 3 부: 다이내믹 BPEL 프로세스의 구현
런타임에 엔드포인트 레퍼런스를 조작하여 다이내믹 바인딩을 구현하는 방법을 설명합니다.
저자 - Sean Carey, Architect, SPS Commerce
Matjaz Juric 제 4 부: WSIF를 이용한 통합
WSIF를 이용하여 BPEL 프로세스가 Java 클래스, EJB 등의 J2EE 리소스에 네이티브한 방법으로 액세스하도록 하는 방법을 배워 봅니다.
저자 - Matjaz B. Juric, University of Maribor
Doug Todd 제 6 부: 워크플로우/프로세스 모니터링을 위한 리치 인터넷 애플리케이션(RIA)의 구현
Oracle BPEL Manager API를 확장하여 실시간 워크플로우/프로세스 모니터링 대시보드를 구현하는 방법을 설명합니다.
저자 - Doug Todd, CTO, Enterra Solutions
Jerry Thomas 제 7 부: BPEL 프로세스의 “즉석” 구현
XQuery를 이용하여 데이터베이스에 저장된 매개변수를 BPEL XML 정의 파일로 변환하고, BPEL 프로세스를 즉석에서 생성하는 방법을 설명합니다.
저자 - Jerry Thomas, Chief Architect, Centerstone Soft
출시 예정인 아티클...

제 5 부: BPEL을 EAI 환경에 추가하기
Oracle BPEL Process Manager의 “orchestration” 기능을 이용하여 표준 기반 비즈니스 프로세스를 통합하고 고전적인 EAI 미들웨어 환경을 보완할 수 있습니다.
저자 - Praveen Chandran and Arun P., Infosys


제 8 부: BPEL 운영자를 위한 가이드
BPEL 프로세스의 구축 및 운영을 위한 커스텀 프로세스 운영 툴을 생성하는 사례 연구입니다.
저자 - Stany Blanvalet

제 9 부: JMS 메시징 버스를 이용한 BPEL의 통합
JMS 호환 버스를 통해 전달되는 메시지에 기반하여 BPEL 프로세스를 다이내믹하게 생성하는 방법을 배워 봅니다.
저자 - Jeremy Bolie, IT Manager, and Todd Beets, Architect, Qualcomm


제 10 부: 포터블 SOA 통합 프레임워크의 구현
메시지의 트랜잭션 무결성을 보장하는 제너릭 BPEL 템플릿을 이용하여 새로운 애플리케이션을 기존 프레임워크에 통합하는 방법에 대해 알아 봅니다.
저자 - Edwin van den Thillart, Interaccess


* 게시 일정은 상황에 따라 변경될 수 있습니다.

Posted by 아름프로
Synapse가 milestone을 발표한 가운데...
ServiceMix와 Synapse의 차이를 헛갈려하는 이들을 위해..
우리의 James아저씨가 명쾌하게 비교를 해주셨네요..

===========================================

Here is an explanation of the difference.

The main difference is, Apache ServiceMix is an ESB based on the JBI standard (JSR 208) whereas Synapse is a mediation framework (or ESB depending on who you talk to) based on the Axis 2 SOAP stack.

James
LogicBlaze
Posted by 아름프로

JavaEE 5, Spring 2 and AspectJ 5: dependecy injection magics


After the Filippo disillusion about Java EE 5 dependecy injection I decided to study the problem of integrating dependecy injection capabilities provided by Java EE 5 and those provided by the Spring framework.


The challange is the following: let's assume that a Stateless EJB, let's say "TestEJB", needs the injection of two POJOs, let's say "TestBean1" and "TestBean2", using two different policies: using JNDI (via @Resource annotation) or without JNDI.


The test EJB and the two test beans implements the following interface:



@Local @Remote
public interface Test {
        public abstract String doTest();
}


The two beans just print out a message and return it; let's show TestBean1 (TestBean2 is similar)



public class TestBean1 implements Test {
        public String doTest() {
                String message = "=>TestBean1";
                System.out.println(message);
                return message;
        }
}


Now let's assume that the TestEJB needs to be injected of instances of TestBean1 and TestBean2 in order to print out and return a message partially composed by TestBean1 and TestBean2:



@Stateless
public class TestEJB implements Test {
        public String doTest() {
                String message = "=>TestEJB";
                System.out.println(message);
                return message + "(" + testBean1.doTest() + "," + testBean2.doTest()

+")";
        }
        
        @Resource(name="beans/TestBean1")
        private Test testBean1;
        
        private Test testBean2;

        public void setTestBean2(Test testBean2) {
                this.testBean2 = testBean2;
        }
}


In order to allow the injection of TestBean1 into TestEJB I found the following solution: let's assume that TestBean1 is defined in the Spring application context as follows:



        <bean id="TestBean1" class="test.TestBean1" />


Now let's populate the JNDI with entries that allow the instantiation of test beans using Spring. I used the following class:



public class SpringBeanFactory implements ObjectFactory {
        private static ApplicationContext appContext;

        private static final String BIND_NAME_PREFIX = "beans/";

        public static void populateJNDI(ApplicationContext appCtx) {
                appContext = appCtx;
                try {
                        Context ctx = new InitialContext();
                        String beansDef[] = appCtx.getBeanDefinitionNames();
                        for (int i = 0; i < beansDef.length; i++) {
                                Class beanClass = appCtx.getType(beansDef[i]);
                                String bindName = BIND_NAME_PREFIX + beansDef[i];
                                Reference reference = new Reference(beanClass.getName(),

new StringRefAddr(bindName,beansDef[i]),
                                                SpringBeanFactory.class.getName(), null);
                                ctx.rebind(bindName, reference);
                        }
                } catch (Exception e) {
                        throw new RuntimeException("Unable to populate JNDI from

application context", e);
                }
        }

        public Object getObjectInstance(Object reference, Name name, Context nameCtx,

Hashtable environment)
                        throws Exception {
                String beanName = (String) ((Reference) reference).get(0).getContent();
                return appContext.getBean(beanName, Object.class);
        }
}


The method "populateJNDI" needs to be invoked with the Spring ApplicationContext instance, for example in the "init" method of a Servlet:



public class TestServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;

        public TestServlet() {
                super();
        }

        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse res) throws

ServletException, IOException {
                StringBuffer buf = new StringBuffer();
                buf.append("<html>");
                buf.append("<body>");
                buf.append("Hello from Servlet");
                buf.append("<br/>");
                buf.append("Hello from chain: ");
                buf.append(testEJB.doTest());
                buf.append("</body>");
                buf.append("</html>");


                res.getOutputStream().write(buf.toString().getBytes());
        }
        
        public void init(ServletConfig config) throws ServletException {
                super.init(config);
                ApplicationContext c =

WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
                SpringBeanFactory.populateJNDI(c);
        }

        @EJB
        protected Test testEJB;
}


That's all, the TestBean1 is avaiable for injection to EJBs using the @Resource(name="beans/TestBean1") annotation.


Now the second problem: I want to inject TestBean2 into TestEJB without registering the the bean into JNDI.


The solution uses Spring 2 integration with AspectJ. Let's assume that in the Spring application context is defined the following:



        <aop:spring-configured/>
        
        <bean id="TestEJB" class="test.TestEJB" lazy-init="false">
                <property name="testBean2">
                        <bean name="TestBean2" class="test.TestBean2"/>
                </property>
        </bean>


Now let's add a Spring2 @Configurable annotation to TestEJB:



@Stateless
@Configurable("TestEJB")
public class TestEJB implements Test {
        ...
}


That's all, by compiling the TestEJB with AspectJ using the "spring-aspects.jar" aspect library provided by Spring2, the TestBean2 will be injected into TestEJB.

( Jan 27 2006, 06:01:20 PM CET ) Permalink Comments [1]


Trackback URL: http://jroller.com/trackback/malbari/Weblog/javaee_5_spring_2_and
Posted by 아름프로
 


ServiceMix as an enterprise service bus

Use ServiceMix 2.0 as a service-oriented message routing framework
Summary
Integrating old and new components and services using a service-oriented architecture requires an infrastructure that can connect any component or service, regardless of location, messaging protocol, and message format. To orchestrate existing services and components to meet the needs of today's dynamic business climate, this infrastructure must be highly customizable. The enterprise service bus (ESB) infrastructure fulfills these requirements. In this article, Jeff Hanson introduces the concepts behind an ESB and discusses the mechanisms it uses to facilitate cross-protocol messaging, message transformation, message security, service invocation, and other requirements of a service-oriented messaging infrastructure. (2,800 words; December 12, 2005)
By J. Jeffrey Hanson


Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend

Page 1 of 2


An enterprise service bus (ESB) is a centralized, logical, architectural component that operates in a distributed, heterogeneous environment to facilitate the requirements of a highly scalable, fault-tolerant, service-messaging framework. An ESB acts as an open and implementation-independent service messaging and interfacing model that isolates application code from the specifics of routing services and transport protocols, and allows substitution of service implementations as needed.

An ESB acts as a shared messaging layer for connecting applications and other services throughout an enterprise computing infrastructure. It supplements its core asynchronous messaging backbone with intelligent transformation and routing to ensure messages are passed reliably. Services participate in the ESB using either Web services messaging standards or Java Message Service (JMS). Originally defined by analysts at Gartner, ESB is increasingly seen as a core component in a service-oriented infrastructure.

In this article, I discuss the open source ESB ServiceMix and its relationship to the Java Business Integration specification.

Minimum requirements of ESB message delivery
The minimum requirements of an ESB, as a message delivery system, are often referred to by the acronym TRANS, which defines an ESB as a software entity that does the following:

  • Transforms messages from one format to another to accommodate the requirements of registered service providers.
  • Routes messages to registered services while providing quality-of-service and service-level features.
  • Augments message content with information, such as additional metadata, about the message requester. Augments the message protocol to meet service provider requirements.
  • Notifies registered message listeners about specific message requests.
  • Secures delivery of messages by enforcing authentication, authorization, nonrepudiation, confidentiality, etc.

Introducing Java Business Integration (JBI)
The Java Business Integration (JBI) specification and API defines a platform for building enterprise-class ESBs using a pluggable, service-based design. JBI builds on the TRANS foundation with normalized messages and component-based interactions.

JBI is a specification and an API for a normalized messaging service along with a component framework and management model for deploying integration services such as routing engines, rule engines, and transformation services. A JBI-based design specifies a standards-based pluggable architecture with a JVM-based runtime component called the normalized message router (NMR).

The high-level interactions of JBI can be seen in Figure 1 below.








Figure 1. High-level view of JBI. Click on thumbnail to view full-sized image.



JBI embodies a messaging model based on Web Services Description Language (WSDL) for easy mapping to Web services, HTTP, email, and JMS. JBI integrates with legacy systems, binary transports, document-oriented transports, and RPC (remote procedure call) systems.

Figure 1's binding components deal with protocol-oriented relationships and components. And service-engine components in JBI support content-based routing, orchestration, rules, transformations, custom augmentation, etc.

Normalized messages
JBI uses a "normalized" message—consisting of a payload, optional attachments, and metadata—for interaction between consumers and providers. Message normalization is the process of mapping context-specific data to a context-neutral abstraction to transport data in a standard format. All messages handled by the NMR are normalized.

A normalized message consists of three main parts:

  1. Message content, also referred to as "payload," which is an XML document that conforms to an abstract WSDL message type with no protocol encoding or formatting.
  2. Message properties or metadata that hold extra data associated with the message. This metadata can include security information, transaction-context information, component-specific information, etc. Message properties form the first part of what is referred to as the message context.
  3. Message attachments referenced by the payload, contained within a data handler used to manipulate the attachment's contents. Attachments can be non-XML data. Attachments form the second part of the message context.

Normalized message router
The JBI message exchange depends on the NMR to route message exchange objects between service consumers and providers. The NMR performs such message delivery with varying qualities of service, depending on application needs and the nature of the messages being delivered.

An NMR is not embodied by any concrete object. It is abstracted as a set of APIs, SPIs (service provider interfaces), and components. The NMR APIs include:

  • JBI Message API
  • JBI Service API
  • JBI Message Exchange Factory API
  • Service Description SPI
  • Message Exchange Patterns API
  • Endpoint Reference API

Delivery channels
A JBI delivery channel represents a bidirectional communication pipe used by binding components and service engines to transport messages across the NMR. The javax.jbi.messaging.DeliveryChannel interface forms the API contract between service consumers, service providers, and the NMR.

A service consumer uses its delivery channel to initiate service invocations, while a service provider uses its delivery channel to receive invocations. A component that functions as both consumer and provider uses the same delivery channel for both roles. Therefore implementations of DeliveryChannel must support concurrent use of a given instance from multiple threads.

Components
The JBI component framework provides a pluggable interface that allows binding components and service engines to interact with the JBI environment. The framework provides the interface to all of the JBI services.

JBI supports two kinds of components, service engines and binding components. Components interact with JBI in two ways:


  1. SPIs: Interfaces implemented by a binding or engine
  2. APIs: Interfaces exposed to bindings or engines by the framework

Service engines
Service engines are the business-logic components in a JBI system and can serve as service providers/consumers. Service engines orchestrate service consumption and requirements. Service engines can also provide services such as data transformation, sophisticated routing, and message coordination facilities.

Binding components
Binding components are used to send and receive messages across specific protocols and transports. They uncouple the JBI environment from protocol specifics by marshalling and unmarshalling messages to and from protocol-specific data formats, allowing the JBI environment to process only normalized messages.

Normalized message exchange
JBI's principal purpose is to route normalized message exchanges from one component to another. Messages are delivered in a normalized form.

Binding components must convert protocol/transport-specific messages to a normalized form. Binding components and service engines interact with the NMR via a delivery channel, which provides a bidirectional delivery mechanism for messages.

An external service consumer sends a service request across a specific protocol and transport to a binding component. The binding component converts the request to a normalized message. The binding component then creates a message packet called a message exchange (ME) and sends it across the binding component's delivery channel to the NMR for delivery to a service provider.

After receiving a message, the consuming service engine or binding component creates a normalized message, putting it into a new MessageExchange instance, and sends it to the target ServiceEndpoint instance. After accepting the ME, the ServiceEndpoint component de-normalizes the message into protocol and transport format, and sends the message along to the external service provider.

Service units
Component-specific artifacts deployed to an installed engine or binding are referred to as service units. Service units are grouped into an aggregate deployment file called a service assembly. This file includes a deployment descriptor that indicates the component into which each service unit is to be deployed.

Service units contain:


  • Metadata: JBI descriptor for services consumed/produced
  • Artifacts: Generally XML (possibly binary, whatever the target binding component or service engine needs)
Next page >
Page 1 ServiceMix as an enterprise service bus
Page 2 Introducing ServiceMix

See JavaWorld Talkback on the last page of this article to post your comments and see how fellow readers reacted.

Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend

Posted by 아름프로
JBI – A Standard-based approach for SOA in Java


December 2005

Discussion



The industry has witnessed the evolution of a wide range of solutions addressing the problem space of B2B and enterprise application integration (EAI). These solutions varied from proprietary message oriented middleware to standard JMS based solutions and web services. This paper provides a brief introduction to the upcoming JBI (Java Business Integration) standard in relation to SOA (service-oriented architecture) principles and the ESB (Enterprise Service Bus) infrastructure.


Service Oriented Architecture


SOA (service-oriented architecture) is one of the latest developments that have made a huge leap in the area of application and business integration. SOA defines a set of well-defined architectural principles, paradigms and best practices to enable loosely coupled interaction between applications.


SOA promotes loosely coupled interaction between participating applications based on well-defined interfaces. Service implementations are self-contained and dont depend on the contextual information and state of other services. Service interactions are mainly based on exchanging document-style data, defined using a standards-based messaging model. The services themselves are agnostic to the transport level interactions required to enable the communication between the service provider and service consumer.


Even though not a mandatory requirement, most of the modern SOA based systems utilise web services and related technologies for providing the required plumbing for the interactions between services. WSDL (Web Services Definition Language) is used as the main artefact for representing messaging models; SOAP as the message representation protocol and HTTP as the wire-level transport protocol. This doesnt mean you always need to use the aforementioned technologies for implementing systems based on service-oriented architecture. Lot of enterprises have used similar architectures for realising loosely coupled systems, well before any of these buzzwords came into existence. However, the key difference is that now we have standards-based protocols, toolsets and software for enabling service oriented architecture.


SOA principles are significantly different from object-oriented paradigms and principles. The key difference is that the interactions between services are defined using interfaces that are oriented more towards data than behaviour. A service in isolation may be realised using object-oriented principles and techniques, however, the interactions between the services seldom use any of these techniques. Rather, these interfaces are geared more towards document-based interchanges. Where object-orientation binds behaviour closer to data, service-orientation decouples data from behaviour.


Enterprise Service Bus


An ESB (Enterprise Service Bus) provides the infrastructure for realising service-oriented architecture. ESBs provide a runtime environment for deploying and enabling your services augmented with design-tools for defining the interaction and orchestration of the services.



In the ESB world the services dont directly interact with each other. Rather, the ESB runtime acts as a mediator between the services to loosely couple them. The ESB runtime would implement protocol bindings, message translation, message handling etc.


The key services provided by an SB would include:



  • Providing transport bindings for the services
  • Providing definition and discovery of the deployed services
  • Rules based routing and orchestration of messages between services
  • Value added services including document transformation etc

Most of the ESB vendors base their SOA proposition on open standards and technologies including the various web services standards and protocols. They provide a variety of transport bindings for invoking the services including HTTP, FTP, and JMS etc. Most ESBs use WS-BPEL (Business Process Execution Language for Web Services) for realising orchestration between the deployed services for implementing business processes. ESB vendors also provide quality of service features including fault-tolerance, failover, load balancing, message buffering etc.


Java Business Integration


JBI (Java Business Integration) is a Java-based standard addressing the EAI and B2B issues based on the paradigms and principles advocated by service-oriented architecture. The current version (1.0) is finalized through the JSR (Java Specification Request) 208 in August 2005. Both commercial and open source worlds have already started embracing JBI as an integration standard in their ESB products.


Mediator-based Architecture


JBI defines a plug-in based architecture where services can be plugged into the JBI runtime environment. JBI provides well-defined interfaces for services to interact with the JBI runtime environment. The services need to expose interfaces to the JBI runtime environment for the JBI runtime environment to route messages to the services. The JBI runtime environment acts as a mediator between the services that are deployed in the environment.



The JBI runtime core mainly comprises of the following components within the same JVM:



  • Component framework: The component framework enables the deployment of the different types of components within the JBI runtime.
  • Normalized Message Router: Normalized message router enables a standard mechanism of message interchange between the services.
  • Management framework: The management framework based on JMX enables the deployment, management and monitoring of components within the JBI runtime.

Component Model


JBI defines two types of components in the JBI runtime environment,



  • Service Engine Components: These are components responsible for implementing business logic and other services. The SE components can internally be realised using various technologies and design principles. SE components can be as simple as a component that provides low-level services like data transformation and translation or something more convoluted as a WS-BPEL instance that models an intricate business process.
  • Binding Components: Binding components are mainly used to provide transport level bindings for the deployed services. BC components can be of a variety of types including,

    • Enabling remote communication with external systems using standard transport protocols.
    • Enable in-VM invocation between two services deployed in the same JVM.
    • Enable communication between services using standard WS-I (Web Services Interoperability) profiles.

The key aspect of JBI is the decoupling of the service engine and binding components so that business logic is not infested with the infrastructure details required for invoking and consuming services. This promotes a flexible and extensible architecture. Both BC and SE components within JBI can be service providers and/or service consumers.


Both BC and SE components provide interfaces to the JBI runtime for accepting messages from the JBI runtime. Similarly, they use interfaces provided by JBI for communicating with the JBI runtime.


Messaging Model


JBI uses a messaging model that decouples the service consumers from the service providers. The messaging model is defined using WSDL. WSDL is used to describe the operations exposed by both SE and BC components. WSDL is also used to define transport level bindings for the abstract service operations.


One of the key components used in the JBI architecture is NMR (Normalized Message Router). NMR provides the main messaging spine built around WSDL, which provides the loosely coupled message exchange between the SE and BC components deployed within the JBI runtime. Services are required to have interfaces, which are an aggregation of operations. Each operation is composed of zero or more messages. An interface can have one or more transport level bindings.


JBI uses a normalized format for representing messages within the runtime. A normalized message is composed of the following parts,



  • Message properties
  • Message payload
  • Message attachments

The JBI specification provides standard interfaces for the service consumers and providers for exchanging messages with the NMR. NMR supports both one-way and request-response semantics for service invocation between consumers and providers.


Management


JBI uses JMX for the runtime installation, configuration and monitoring of services. The services are required to implement a set of JBI interfaces to make them manageable in the JBI environment. The JBI environment is required to provide a set of JMX MBeans to enable the management of the JBI runtime.


The JBI runtime environment allows the following operation related to the SE and BC components,



  • Installation of components: This will make the component interface available to the normalized message router.
  • Installation of component artefacts: This will allow deployment of component artefacts required for the functioning of installed components. For example, this could be deploying the connection details required to connect to a database for a deployed service that requires connecting to the database.
  • Starting and stopping of services and groups of related services.

JBI defines standard deployment descriptors and packaging models for both components and component artefacts.


Roles


JBI identifies the following roles for providing an end-to-end JBI based EAI solution,



  • Engine developers: Engine developers are required to provide the SE components that adhere to the NMR and management contracts.
  • Binding developers: Binding developers provide the binding components that adhere to the NMR and management contracts.
  • JBI Environment providers: JBI environment providers are required to support the JBI runtime using either J2EE 1.4 or J2SE 1.4 r newer platform.
  • J2EE Platform providers: J2EE platform providers may include a JBI runtime as part of their application server offerings.
  • JBI Application developers: JBI developers build JBI applications using the SE and BC components and the JBI environment.

Conclusion


With the whole industry aligning more and more towards open standards and specifications, JBI takes a great leap in enabling Java technologists adopting a standards-based approach in addressing integration issues using service oriented architecture and ESB infrastructure. Both commercial vendors like Oracle and open source software like ServiceMix have already started adopting JBI as part of their ESB offerings.


About the Author


Meeraj Kinnumpurath works as a Java architect with VOCA Ltd (formerly BACS), who are the largest clearing house in Europe. He has been using Java for the past eight years, developing enterprise applications. He has also published a few books on Java, J2EE and Web Services.


PRINTER FRIENDLY VERSION

Posted by 아름프로

Web Services + EA = SOA

2005. 10. 26. 16:54

Web Services + EA = SOA

.최근 정보기술의 방향에서 중요한 키워드 중 하나가 바로 서비스(Service)이다. 서비스는 정보기술이 현실에서 지향하는 바를 한 마디로 설명할 수 있는 중요한 단어이다. 서비스 지향 아키텍쳐(Services-Oriented Architecture; 이하 SOA) 역시 서비스의 관점에서 소프트웨어 아키텍쳐를 조망하는 기술로 최근 많은 각광을 받고 있으며, 시장조사업체인 가트너 그룹은 2006년까지 전 세계 비즈니스 애플리케이션의 80% 이상이 SOA를 기반으로 개발될 것이라고 전망하고 있다.
..SOA의 설명을 위해 자연스럽게 떠올리게 되는 두 가지 키워드가 웹 서비스(Web Services)와 전사적 아키텍처(Enterprise Architecture; 이하 EA)이다. 웹 서비스와 EA는 기업 및 공공기관에서 가장 관심을 높게 보이는 기술 이슈이다. 국내의 모든 공공기관들은 EA를 필히 구축해야 하고 전자정부 애플리케이션의 통합 및 연계를 위해서는 기업에 종속적인 EAI 메카니즘이 아닌 표준화된 기술 즉, 웹 서비스를 반드시 적용하도록 규정하고 있다.
..본 고에서 다루고자 하는 내용은 국가적 필수 적용 기술인 웹 서비스, EA와 새로이 떠오르고 있는 기술인 SOA의 관계를 도출하는 것이다. 그렇게 함으로써 SOA의 적용에 Web Services와 EA가 어떤 역할을 할 수 있는 지를 파악하고자 한다.
..이를 위해 먼저 SOA의 개념에 대해 간단히 설명한 후 Web Services, EA와의 관련성을 각각 분석한 후 결론 부문에서 이들 세 기술간의 관계를 도출하였다.

SOA 개

..SOA는 소프트웨어 아키텍처의 일종이다. 따라서, SOA를 이해하기 위해서는 이를 구성하고 있는 요소들을 파악할 필요가 있는데, 본 절에서는 먼저 SOA와 서비스를 정의하고 이를 기반으로 구성요소들을 살펴보도록 한다.


    1) SOA의 정의
    ..사실 SOA는 이미 CORBA나 DCOM등의 분산 객체 기술에서 그 기본 개념이 사용되었으나, 기술적인 문제(기술적인 미성숙 및 공개 표준의 부재)와 비즈니스 문제들(주요 소프트웨어 벤더들 간 협력의 부재)로 인하여 그리 큰 주목을 받지 못했다. 하지만 XML 기반의 웹 서비스 기술이 등장하면서 SOA는 새롭게 조명을 받고 있다.
    ..W3C는 SOA를 "호출 가능한 컴포넌트의 집합"으로 정의 하고 있다. 여기서 컴포넌트는 그 인터페이스의 정의 내용이 공개(publish)?발견(discovery) 가능한 것을 의미한다.
    ..하지만 CBDI는 이 정의에 대해 두 가지 문제점을 지적하고 있다. SOA가 단순한 컴포넌트의 집합이 아니라는 점과, 정의 자체가 아키텍처의 구성 방법 보다는 이미 정의되어 있는 컴포넌트만을 염두 해두고 있다는 점이다. 따라서 CBDI는 SOA를 "애플리케이션의 기능들을 사용자(consumer)에 적합한 크기(granularity)로 공개한 서비스들의 집합으로 제공하고 사용되게 하는 정책(policy), 적용(practice), 또는 프레임워크(framework)"로 정의하고, 이 때 서비스는 "단일한 표준기반의 인터페이스 형태를 사용하여 구현과 독립적으로 추상화되며, 호출(invoke)되고, 공개(publish)되며, 발견(discover)할 수 있는 것"이라 정의하였다.
    ..즉, SOA란 서비스라 불리는 분할(decomposition)된 애플리케이션 조각들을 단위로 느슨하게 연결해 하나의 완성된 애플리케이션으로 만드는 아키텍처이다.

    2) SOA의 구성요소
    ..<그림 2>는 SOA의 기본 구성요소를 도시하고 있는데, 각 요소는 다음과 같다.



    - 서비스 사용자(Service Consumer) : '서비스 제공자'에 의해 제공되고 있는 하나 이상의 서비스를 사용한다.
    - 서비스 제공자(Service Provider) : '서비스 사용자'가 호출시 입력하는 값을 가공하여, 그에 해당하는 결과를 제공한다. 경우에 따라 '서비스 제공자'는 또 다른 - - '서비스 제공자'의 서비스를 사용하는 '서비스 사용자'가 될 수도 있다.
    - 서비스 레지스트리(Service Registry) : 서비스에 대한 설명 정보(descriptions)를 저장하고 있다. '서비스 제공자'는 자신이 제공하고 있는 서비스를 등록하고, '서비스 사용자'는 자신의 원하는 서비스를 발견하여 사용한다.

<그림 2> SOA의 구성 요소

위의 그림으로부터 우리는 SOA를 이해하기 위한 세가지 주요 요소를 추출할 수 있다. 서비스, 메시지 그리고 서비스 발견 등이 그것이다. 이들 각각에 대한 이해를 통해, 우리는 SOA의 본질에 보다 가까이 갈 수 있다.


<그림 3> 서비스의 구조

가. 서비스(Services)
..SOA의 관점에서 서비스는 인터페이스를 통해 자신이 가진 비즈니스 프로세스를 처리할 수 있는 컴포넌트로 정의된다. <그림 3>과 같이 서비스는 인터페이스와 구현 부분으로 구성된다. 서비스가 가지는 특징을 다음과 같이 3가지로 요약할 수 있다.
..- 서비스의 인터페이스는 플랫폼에 독립적이다
..- 서비스는 동적으로 검색될 수 있으며, 호출될 수 있다.
..- 서비스는 self-contained하다. 즉, 자신의 상태를 스스로 유지한다.
..서비스의 탄생으로 인해 자체적으로 소프트웨어를 만드는 기업은 점차 사라지고, 향후에는 만들어져 있는 소프트웨어를 서비스 단위로 구입하여 사용하는 패러다임이 대세를 이룰 것으로 예상된다.
나. 메시지 (Messages)
..SOA를 이루는 두 번째 중요한 개념은 메시지이다. 서비스 제공자와 서비스 사용자는 메시지를 통해 서로 통신한다. 서비스 제공자는 서비스 명세를 통해 자신이 가진 서비스의 인터페이스를 공개하는데, 이 명세 내에는 서비스가 제공하는 기능과 이를 이용하기 위해 사용자와 주고 받아야 하는 메시지의 형식이 정의되어 있다. SOA 관점에서 서비스는 플랫폼 독립적이어야 하므로, SOA에서 정의되는 메시지는 특정 기술에 독립적이어야 한다. <그림 4>는 서비스 제공자와 서비스 사용자가 메시지를 통해 통신하는 모습을 보여준다.




<그림 4> 메시지를 통한 서비스 사용 구조



..이러한 SOA 메시지를 체계를 응용하면 <그림 5>와 같이 보다 복잡한 아키텍처를 구성할 수 있다. 그림과 같이 서비스 제공자는 동시에 서비스 사용자가 될 수 있다. 서비스 제공자는 다른 서비스 제공자로부터 비즈니스 프로세스나 컨텐츠 등을 제공 받아 보다 가치 있는 서비스를 제공할 수 있다.


<그림 5> 서비스 통합 구조



다. 서비스 발견(Discovery)
..서비스 발견이란 서비스 사용자가 서비스 레지스트리로부터 자신의 원하는 서비스 제공자를 찾는 작업을 말한다. 이를 위해서는 서비스 레지스트리는 서비스를 등록하고 발견하는 기능을 제공해야 한다. SOA의 관점에서 서비스 레지스트리는 다음과 같은 요구사항을 만족해야 한다.
..- 서비스의 확장성(scalability) 보장
..- 서비스 사용자와 제공자의 분리 (decoupling)
..- 서비스의 동적인 변경 기능 제공 (hot update)
..- 서비스 사용자를 위한 검색 기능 제공 (동적인 검색 기능 포함)


3) SOA의 특징
..SOA가 가지고 있는 중요한 특징을 정리하면 다음과 같다.



- 서비스는 발견이 가능하고 동적으로 바인딩 된다.
- 서비스는 컴포넌트와 같이 독립된 모듈이다.
- 서비스의 플랫폼간 상호 운용이 가능하다.
- 서비스는 느슨하게 연결된다.
- 서비스는 네트워크 주소로 접근 가능한 인터페이스를 갖는다.
- 서비스는 위치 투명성을 제공한다.
- 서비스의 조립이 가능하다.
- 서비스는 자기 치유(self-healing)를 지원한다.


4) SOA의 이점
..SOA는 기업 내의 어플리케이션 아키텍처를 보다 유연하고 확장 가능하도록 구성할 수 있게 하는 패러다임이다. 이러한 특징으로 인해 기업은 SOA를 통해 다음과 같은 이점을 얻을 수 있다.



- 기존 자산을 최대한 이용할 수 있게 한다.
- 빠른 시장 접근이 가능케 한다.
- 전반적인 IT 비용을 절감해준다.
- 위험관리를 용이케 한다.
- 끊임없는 비즈니스 프로세스의 진보를 이루게 한다.
- 프로세스 중심의 아키텍처를 유지할 수 있게 한다.


SOA vs. Web Services


..SOA와 웹 서비스의 관계는 많은 자료에서 언급하고 있다. 일반적으로 그 내용은 거의 유사하지만 제시하는 기관마다 약간의 시각차이가 존재하고, 특히 SOA를 정의하는 관점에 따라서도 차이가 존재한다. 여기서는 여러 자료를 토대로 SOA와 웹 서비스의 관계를 도출하고 구체적으로 웹 서비스를 통해 SOA를 구현하는 방법까지 정리하였다.


1) SOA와 웹 서비스의 관계
..SOA는 웹 서비스 개념보다 먼저 출현하였으며, 웹 서비스 보다 포괄적인 개념이다. SOA는 소프트웨어 개발 패러다임에 가깝고, 웹 서비스는 이러한 SOA의 패러다임을 실현하기 위한 다양한 기술 구현 사례라고 할 수 있다. 이름에서 알 수 있듯이 SOA는 아키텍처이다. 웹 서비스와 달리 특정 기술의 집합이 아니다. SOA는 기술적인 것을 초월할 뿐만 아니라 기술로부터 독립적이다. 비즈니스 환경에서 SOA의 순수한 아키텍처적인 정의는 "호출 가능한 잘 정의된 인터페이스를 갖는 독립된 기능의 서비스로 정의한 애플리케이션 아키텍처"이다. 반면, 웹 서비스는 기술의 집합이며 SOA의 개념을 보다 구체화한 것이다. <그림 6>은 이들 간의 관계를 개념화한 것이다.


<그림 6> SOA와 웹 서비스의 관계



..웹 서비스는 단순히 SOA를 구현한 것만은 아니다. 웹 서비스는 SOA 구현의 Best Practice라고 할 수 있다. 왜냐하면 SOA의 근본적인 철학을 고스란히 실현할 수 있도록 플랫폼 독립적인 프로토콜과 기술을 채택했기 때문이다. 앞에서도 밝혔듯이 웹 서비스가 HTTP, XML, SOAP, WSDL, UDDI 등의 프로토콜을 채택한 것은 SOA의 기본적인 요구사항을 만족하기 위해서라고 할 수 있다. 이들 기술은 특정 컴퓨팅 기술에 중립적이며, de-facto 표준에 가깝다.
..웹 서비스는 SOA를 개념 수준에서 구현이 가능한 현실로 끌어올리는데 중요한 역할을 한다. 현재도 웹 서비스를 이루는 기술표준들은 진화하고 있으며, 이들이 보다 견고해짐에 따라 SOA를 채택하기 위한 위험요소도 점차 제거될 것으로 기대된다.


2) 웹 서비스를 이용한 SOA의 구현
..SOA에서 기본적으로 요구하는 컴퓨팅 관련 사항과 웹 서비스의 대응 기술은 다음과 같다.



- SOA는 플랫폼 독립적인 방식으로 호출될 수 있는 서비스로 구성된다 - XML, SOAP
- 서비스는 플랫폼, 프로그래밍 언어에 독립적인 인터페이스를 갖는다. - WSDL
- 서비스는 표준체계에 의해 등록이 가능하며, 동적으로 발견 가능하다. - UDDI


..웹 서비스는 W3C SOAP 1.2 표준을 통해 서비스 사용자와 제공자 사이의 통신을 구현한다. <그림 7>은 이를 표현한 것이다.

<그림 7> SOAP을 통한 서비스 호출

..웹 서비스에서 사용하는 서비스 기술의 표준은 WSDL이다. WSDL은 서비스 사용자와 제공자가 주고 받을 메시지를 XML로 정의하며, 모든 프로그래밍 언어에 독립적으로 작동한다.


<그림 8> WSDL을 통한 웹 서비스의 기술


<그림 9 > UDDI의 동작 패턴

SOA vs. EA


..SOA와 EA의 관계는 다양한 시각에서 논의되고 있다. 이 둘의 관계는 바라보는 관점이나 적용 범위에 따라 차이가 있을 수 있으나 SOA가 EA의 하위 아키텍처를 구성한다는 관점과 SOA와 EA가 상호보완적 개념이라는 관점이 언급되고 있다. 여기서는 이러한 SOA와 EA의 관계에 대한 몇 가지 관점들에 대해 설명해 보고자 한다.



1) SOA를 EA의 하위 아키텍처로 보는 관점
..<그림 10>처럼 SOA를 EA의 하위 아키텍처의 구현 방안으로 보는 시각으로서 SOA가 EA의 기술 부문 (데이터/애플리케이션/기술)의 아키텍처라는 시각과 EA의 애플리케이션/기술 아키텍처의 일부라는 시각으로 나뉘어 진다. 이들은 SOA를 비즈니스 관점에서는 배제하고 주로 기술 관점, 특히 기업 애플리케이션을 구현하기 위한 기술 아키텍쳐 관점에서 주로 SOA를 바라보고 있다.

<그림 10> EA의 하위 아키텍처로서의 SOA


가. SOA는 EA의 기술부문(데이터/애플리케이션/기술)에 해당한다.
..SOA가 EA의 기술부문, 즉 데이터/애플리케이션/기술 아키텍처에 해당한다는 관점으로 비즈니스 프로세스 구현에 필요한 기술적인 사항들을 SOA로 구성할 수 있으며 이를 통해 EA가 추구하는 유연하고 민첩한 구조를 달성한다는 관점이다.


<그림 11> SOA를 통한 분산 데이터 아키텍처의 구현


SOA를 통한 조직의 데이터 아키텍처 변화를 <그림 11>에서 표현하고 있다. 이처럼 각각의 서비스가 관련된 데이터를 직접 관리하는 분산 데이터 환경으로 변화하게 된다.

나. SOA는 EA 기술아키텍처를 구성하는 패턴(Pattern)의 하나이다.
..이 관점은 가트너 그룹에서 주장하는 EA와 SOA의 관계로 SOA는 EA를 구성하는 하나의 기술 패턴이라는 관점이다. 패턴이란 '정해진 문제점에 대하여 여러 사람들이 공감하는 해결책'이라고 할 수 있다. 이는 <그림 12>의 가트너 EA 프레임워크를 통해 이해할 수 있다. 여기서는 일반적인 매트릭스 형태의 EA 프레임워크와 달리 EA 구성요소들의 수직적이고 계층적인 관계에 중점을 두고 있다.

<그림 12> 가트너 EA 프레임워크와 SOA


..가트너의 EA 프레임워크에서 SOA의 위치를 살펴보면 비즈니스 프로세스/스타일 하부의 기술 패턴에 위치하고 있으며 SOA의 구현과 관련된 기술들은 패턴의 하부를 구성하는 기술 단위체인 벽돌(Brick) 레벨에 위치하고 있는 것을 알 수 있다.


2) To-Be 아키텍쳐의 구현 방안으로서의 SOA
..EA는 그 정의에서 알 수 있듯이 As-Is 아키텍처와 To-Be 아키텍처 그리고 To-Be 아키텍처의 구현계획과 관련된 표준/가이드로 구성 되어 있다. To-Be 아키텍처의 구현 방법으로는 신규 개발, 외부도입, 기존 시스템의 전환(migration) 등의 방안이 있으며, 이중 기존 시스템의 전환 방안에 SOA가 적용 될 수 있다. 이는 CBDi에서 제시하는 방안으로 <그림 13> 과 같이 기존 시스템을 전환할 수 있다. 초기에는 획일적인 형태의 레가시 시스템을 웹 서비스와 같은 SOA에 적합한 기술을 적용하여 래핑을 실시하여 외부와의 인터페이스를 정형화한 후 최종적으로는 래핑한 내부의 레가시 시스템을 컴포넌트로 재정립함으로써 완전한 형태의 SOA 구조로 변환할 수 있다.

<그림 13> SOA를 이용한 As-Is 아키텍처의 Migration

..이처럼 SOA는 기업의 최종 목표 시스템 아키텍쳐를 구현하기 위한 방안으로서 가장 적절한 대안이라고 할 수 있다.

3) SOA와 EA의 관계
..앞에서 언급된 여러 가지 SOA와 EA의 관계를 분석해 보면, SOA는 EA와 매우 밀접한 관계를 가지고 있다는 것을 알 수 있다. 이들을 다시 정리해 보면, SOA를 단순히 EA의 하위 아키텍쳐로 바라봄으로써 단순히 기술 아키텍쳐를 표현할 수 있는 패턴으로 보는 관점과 보다 넓은 관점에서 미래 지향형 EA를 구축하기 위한 방안으로 볼 수 있다.
..두 가지 관점 모두 의미가 있지만, 후자의 관점이 보다 설득력이 있다. 결론적으로, SOA는 EA가 추구하는 목표들은 명확하게 달성할 수 있게 해주며, EA가 제공하는 조직의 전사적 구조는 SOA의 적용을 용이하게 해주는 상호보완적 관계라고도 할 수 있다.



<그림 14> SOA와 EA의 관계

..이를 그림으로 표현해보면 <그림 14>와 같다. 즉, 'SOA 개념이 EA에 반영되어 내재화됨으로서 조직의 정보기술구조를 보다 유연하고 민첩하게 할 수 있다'라고 정의하는 것이 바람직하다.


Web Services + EA = SOA ??


..지금까지 SOA, 웹 서비스, EA에 관한 개념과 이들 상호간의 관계에 관하여 다각적인 측면에서 조망해 보았다. 아직은 초기 단계이기 때문인지 대다수가 정답으로 받아들이는 내용은 아직 없다.
그래서 본 고에서는 이들 간의 관계를 주관적이긴 하지만 앞선 연구결과들의 객관성을 반영하면서 전체가 지향하는 방향에 맞게 이들의 관계를 정립해 보았으며, 최종 SOA 방정식의 결과로 아래의 두 가지 명제를 도출하였다.
.."웹 서비스는 SOA의 구현을 위한 현존하는 최적의 기술 대안이다."
.."SOA는 차세대(To-Be) EA 구현을 위한 최적의 아키텍쳐이다."
..이를 그림으로 표현하면 <그림 15>와 같다. SOA는 EA의 모든 부분을 구현할 수 있는 차세대 아키텍쳐이며, 웹 서비스는 SOA의 기술 도메인과 EA의 기술 아키텍쳐, 비즈니스 프로세스 영역을 담당하고 있으며, SOA 구현을 위한 최적의 기술이라고 할 수 있다.


<그림 15> Web Services + EA = SOA ??

..SOA의 구현을 위한 가장 최적의 기술이 웹 서비스라고 한다면 웹 서비스 성공의 1차 관건은 SOA라는 철학을 기업의 EA에 반영하는 것이다. EA에 반영된 SOA는 EA의 활용/진화 과정을 통해, 웹 서비스 형태로 기업에 내재화 될 것이며 이를 통해 기업은 정보기술분야의 효용성을 증대 시킬 수 있을 것이다.
..이러한 구조는 기업의 정보시스템 구조를 느슨하게 연결된(Loosely Coupled) 형태로 만들어 변화하는 비즈니스 환경에 보다 유연하고 신속하게 대응할 수 있는 능력을 제공한다. 즉, 비즈니스 환경이 변하여 그에 대한 정보기술부문의 요구사항이 발생하면 EA에 정의되어 있는 SOA에 관련된 기술, 표준 등을 통해 자체적으로 서비스를 개발하거나 표준화된 인터페이스에 적합한 외부 서비스를 서비스 중개자(Service Broker)를 통해 조달 하여 비즈니스 부문의 요구사항에 보다 신속하게 대응 할 수 있는 것이다.
..긍극적으로 SOA, 웹 서비스, EA는 미래지향적인 기업의 정보기술구조를 구현하고 관리하기 위해 꼭 필요하며, 이들은 서로가 독립적으로 위치하기도 하지만 상호간에 연결도가 높은 철학, 기술, 개념이라고 할 수 있다

Posted by 아름프로





Java generics support in Eclipse V3.1

developerWorks














Document options


















Set printer orientation to landscape mode

Print this page

Email this page

E-mail this page

Document options requiring JavaScript are not displayed






Rate this page











Help us improve this content



Level: Intermediate


Neal Ford (nealford@nealford.com), Application Architect, ThoughtWorks


18 Oct 2005


Java™ 5 offers generics support, a feature developers requested for years. It represents a significant upgrade to the Java programming language. With something as complex as generics also comes challenges, both for tool vendors and developers. This article highlights how Eclipse has responded and the changes wrought by generics to the Java language. It shows how to take full advantage of generics within Eclipse, including support in Quick Assist, Quick Fix, refactoring, and project preferences. It also shows some subtle and important aspects of a fully generic language.

Generics in Java


The creators of Java technology have talked about adding generics support to the language almost since the first version. C++ supports generics through the Standard Template Library, but the implementation is hampered by the lack of a single unified parent class for all other classes (embodied in the Object class in Java). The generics support in the Java programming language is the most significant syntax change in its history. Tools support has proceeded more slowly than for other SDK upgrades for obvious reasons. Now, though, you have excellent support for these new language features in Eclipse V3.1. This article highlights some of these new features.
















Back to top



Java 5 Projects


To turn on generics support in Eclipse V3.1, you need Java 5 on your machine, which you can download from the usual places. The generics support comes along with project properties in the compiler settings pages. That means you can have separate SDK settings per project, just as in the past. To create a project that uses generics, you have to specify the language level during the creation of the project or through the project properties of an existing project.


Two specific property pages pertain to Java 5 settings. The first specifies compiler settings.


Figure 1. Compiler-specific settings for Java 5 support
Compiler-specific settings for Java 5 support

Unless you have set the default project settings in Eclipse for Java 5, you will need to override those settings for this project. The JDK compliance section allows you to determine the settings for source and class files. When setting level 5.0 for source files, you get a slew of new Content Assist and refactoring options.


The other pertinent properties dialog is the Errors/Warnings section in the tree view.


Figure 2. The Errors/Warnings section of project properties
The Errors/Warnings section of project properties

The wealth of J2SE 5 options control what kinds of errors and warnings (see Table 1) Eclipse will generate for your Java 5 code.





































Table 1. Errors and warnings Eclipse will generate for Java 5 code
J2SE 5 options Type of warning
Unchecked generic type operation The compiler will issue an error or warning whenever it encounters an unchecked generic type operation. This includes operations on types like List or ArrayList without a type specified. This provides a warning any time you use an old-fashioned Collection class that holds objects.
Generic type parameter declared with a final type bound The compiler will issue an error or warning whenever it encounters a type bound involving a final type. Consider this sample method signature:

public int doIt(List<? extends String> list)


Because String is final, the parameter cannot extend String, so it is more efficient to write it like this:

public int doIt(List<String> list)
Inexact type match for vararg arguments The compiler generates a warning when it cannot exactly determine the developer's intent from a varargs parameter. There are some varargs involving arrays that are ambiguous.
Boxing and unboxing conversions Warns about automatic boxing operations, which may impact performance, and breaks assumptions about object identity for type wrapper objects. This is a minor warning ignored by default.
Missing @Override annotation You should include the @Override annotation for any overridden method. A missing annotation may indicate that the developer didn't realize the method was being overridden.
Missing @Deprecated annotation Warning about leaving off the @Deprecated flag.
Annotation is used as super interface You shouldn't use the Deprecated class as a super interface. For example, this is frowned upon:

public interface BadForm extends Deprecated {


}

.
Not all enum constants covered on switch Missing enumerations on a switch statement, meaning that you may miss some enumerated options.
Unhandled warning tokens in @SuppressWarnings Java 5 allows you to add annotations to suppress warnings from the compiler. If you misspell the warning or use a warning that doesn't exist, this flag will issue a warning.
Enable @SuppressWarnings annotations Turns on the ability to programmatically (in code) suppress warnings you don't care about.

Once you have all your project options set to your liking, you can start using generics in Eclipse.
















Back to top



Porting from Specific to Generic


Consider this simple class in Listing 1, which creates a list of Employee and Manager objects (Manager extends Employee), prints them, gives them a raise, then prints them again.


Listing 1. The HR class






package com.nealford.devworks.generics.generics;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HR {

public HR() {
List empList = new ArrayList(5);
empList.add(new Employee("Homer", 200.0, 1995));
empList.add(new Employee("Lenny", 300.0, 2000));
empList.add(new Employee("Waylon", 700.0, 1965));
empList.add(new Manager("Monty", 2000.0, 1933,
(Employee) empList.get(2)));

printEmployees(empList);

System.out.println("----- Give everyone a raise -----");
for (int i = 0; i < empList.size(); i++)
((Employee) empList.get(i)).applyRaise(5);

printEmployees(empList);

System.out.println("The maximum salary for any employee is "+
Employee.MAX_SALARY);

System.out.println("Sort employees by salary");
Collections.sort(empList);
printEmployees(empList);

System.out.println("Sort employees by name");
Collections.sort(empList, new Employee.NameComparer());
printEmployees(empList);

System.out.println("Sort employees by hire year");
Collections.sort(empList, Employee.getHireYearComparator());
printEmployees(empList);

}

public void printEmployees(List emps) {
for (int i = 0; i < emps.size(); i++)
System.out.println(emps.get(i));
}

public static void main(String[] args) {
new HR();
}
}


If you turn on Java 5 support, a variety of warnings will light up for this code.
















Back to top



Quick Fix features


The Quick Fix feature in Eclipse appears as a lightbulb in the editor gutter anytime Eclipse wants to suggest an improvement to your code. In the code from Listing 1, you will see a variety of Quick Fixes.


Figure 3. The Quick Fix lightbulbs indicate potential improvements to your code
Quick fix

Quick Fix provides a lightbulb and a wavy yellow line indicating improvements. If you roll over the wavy yellow line, you will see the suggestion that appears in Figure 4.


Figure 4. The Quick Fix indicates what should be generified
Quick Fix indicates what should be generified

The Quick Fix suggestion listed here is just that -- a suggestion. The lightbulbs in the gutter are offered to add a local variable for the return of the add() method of List, which returns a boolean, which is ignored, in this case.


To address the Quick Fix suggestion, move to the refactoring menu. A few refactorings in Eclipse directly relate to generics in Java 5. The "Infer Generic Type Arguments" refactoring will add generics support to the list. The first dialog allows you to pick options.


Figure 5. Infer Generic Type Arguments choices dialog
 Infer Generic Type Arguments choices dialog

The first option relates to the inference that the clone() method will return the receiver type, not another (related class). Well-behaved classes generally observe this rule; uncheck this box if you know that your class doesn't. The second option, when unchecked, will leave the "raw" (nongeneric) parameter in place, rather than infer the correct generic parameter type.


As in most refactorings in Eclipse, you can preview what changes will occur in your class. The Preview button on this dialog yields the dialog shown in Figure 6.


Figure 6. Preview the generic refactoring
Preview the generic refactoring

The updated code looks like this:


Listing 2. Updated code






List<Employee> empList = new ArrayList<Employee>(5);
empList.add(new Employee("Homer", 200.0, 1995));
empList.add(new Employee("Lenny", 300.0, 2000));
empList.add(new Employee("Waylon", 700.0, 1965));
empList.add(new Manager("Monty", 2000.0, 1933,
empList.get(2)));


Two interesting changes have occurred to the code. First -- and most obvious -- the List and ArrayList declarations are now generic for Employee types. The second -- more subtle -- change is in the last line. If you look at the original empList addition of the Manager class, it requires a typecast to an Employee for the Assistant field in the last parameter. The Infer refactoring was smart enough to remove the now unnecessary type cast.


Before leaving Quick Fix, there is one other aspect that is interesting in the Java 5 support added by Eclipse: You can now receive suggestions for supplying annotations for methods, such as @Override. You also have Content Assist for annotations.


Figure 7. Quick Fix and Content Assist extends to annotations
Quick Fix and Content Assist extends to annotations















Back to top



Quick Assist features


Eclipse V3.1 has added a Quick Assist to facilitate generics support in Java 5. Consider this mundane for() loop, found in the printEmployees() method shown in Listing 3.


Listing 3. The for() loop






public void printEmployees(List<Employee> emps) {
for (int i = 0; i < emps.size(); i++)
System.out.println(emps.get(i));
}


Along with support for generics, Java 5 now supports a for...each loop. Quick Assist offers to change this for loop into a for...each, which yields the code shown in Listing 4.


Listing 4. The for...each loop






public void printEmployees(List<Employee> emps) {
for (Employee emp : emps)
System.out.println(emp);
}


This version is much cleaner because it eliminates the i variable and the call to get() entirely.
















Back to top



Generic types


Eclipse V3.1 has also expanded its support for type operations to extend to generic types. This means:



  • Generic types can be safely renamed.
  • Type variables can be safely renamed.
  • Generic methods can be extracted from or inlined into generic code.
  • Code Assist can automatically insert appropriate type parameters in parameterized types.

The search facilities in Eclipse have also gotten more intelligent with generic types. Consider this:


Listing 5. Generic types






public void doEmployeeAnalysis() {
List<Employee> empList = new ArrayList<Employee>(5);
List<Date> hireDates = new ArrayList<Date>(5);
List<Integer> departments = new ArrayList<Integer>(10);
List<? extends Employee> allMgrs = new ArrayList<Manager>(5);
. . .


If you highlight the first List<Employee> declaration and select Search > References > Project, Eclipse will show you all the list declarations.


Figure 8. Eclipse has gotten smart about finding generic references
Eclipse has gotten smart about finding generic references

You can also filter these results via a well-hidden feature of the Search window. If you access the Search window menu (in the right-hand corner, beside the minimize and maximize buttons), you get generics-aware filtering options.


Figure 9. The filter menu of the search window allows you to filter generics-aware results
The filter menu of the search window allows you to filter generics-aware results

If you filter the results using Filter Incompatible, it eliminates the two entries that are not Employee-based. The results are shown in Figure 10.


Figure 10. Filter Incompatible filters out the non-Employee related entries in the search window
Filter Incompatible filters out the non-Employee related entries in the search window















Back to top



Digging deeper in generics


Unfortunately, Eclipse cannot solve all your generics problems. In fact, sometimes refactorings yield syntactically correct code that is not semantically correct for the problem you are trying to solve. Ironically, life was easier in the pre-generics days because you had to pass everything as generic collections of objects. Now you must be careful to pass the right type of collection.


Consider this example. In the HR application, you add a method that determines retirement age for employees. However, the age of the Employee comes from the Employee super class: Person. Writing a method that takes just employees would work in this one instance, but you do not want to restrict the application to work only with employees. What if you need to trace former employees (as Persons) in the future?


The solution to this problem lies with flexible generic parameters. Consider the code in Listing 6, which accepts any class that extends Person.


Listing 6. Sample SELECT statement






public List<Person> empsOverRetirementAge(
List<? extends Person> people) {
List<Person> retirees = new ArrayList<Person>(1);
for (Person e : people)
if (e.getAge() > 65)
retirees.add(e);
return retirees;
}


This method accepts any subclass of Person and is, therefore, more flexible. You should keep this in mind when using generics. In this case, the generic is actually more specific (they should have called this language feature "specifics," anyway). Carefully identifying your parameter types allows you to achieve the same level of flexibility in your code that you had prior to generics, but with the added type security that generics provide.
















Back to top



Summary


Generics support is a huge enhancement to the Java programming language, necessitating a long time for tool vendors to catch up. Now that you have good tool support, you should start taking advantage of this advanced language feature. It makes code more readable -- because you eliminate type casts -- and allows the compiler to do more work on your behalf. Anytime you can get compilers and other tools (like IDEs) to perform more work, it means less work for you.
















Back to top



Resources

Learn


Get products and technologies


  • Innovate your next open source development project with IBM trial software, available for download or on DVD.


Discuss
















Back to top



About the author









Neal Ford


Neal Ford is an application architect at ThoughtWorks, an IT professional services company. Neal designs and develops applications, instructional materials, magazine articles, courseware, video/DVD presentations, and wrote the books Developing with Delphi: Object-Oriented Techniques, JBuilder 3 Unleashed, and Art of Java Web Development. His primary consulting focus is the building of large-scale enterprise applications. He has also been a speaker at developer conferences.

Posted by 아름프로





Get a better handle on Struts actions, with Spring


Three ways to integrate Struts applications with Spring















Document options


























Set printer orientation to landscape mode

Print this page

Email this page

E-mail this page

Document options requiring JavaScript are not displayed


Discuss


Sample code






Rate this page











Help us improve this content



Level: Intermediate


George Franciscus (george.franciscus@nexcel.ca), Principal, Nexcel


11 Oct 2005


Struts Recipes co-author George Franciscus is back with another great Struts integration recipe -- this time for importing Struts applications into the Spring framework. Follow along as George shows you how to revamp Struts actions so they can be managed just like Spring beans. The result is a boosted web framework that easily reaps the benefits of Spring AOP.

The Inversion of Control (IOC) design pattern has been generating buzz for long enough now that you've surely heard of it. If you've used the Spring framework in any capacity, then you've seen its principles in action. In this article, you'll learn about the power of the IOC pattern first-hand as I use its principles to inject a Struts application into the Spring framework.


The advantages of integrating a Struts application into the Spring framework are manifold. First off, Spring was explicitly designed to resolve some of the real-world problems of JEE, such as complexity, poor performance, testability, and much more. Second, the Spring framework includes an AOP implementation that lets you apply aspect-oriented techniques to normal object-oriented code. Third, some might say that the Spring framework just handles Struts better than Struts handles itself. But that's a matter of opinion, so follow along as I demonstrate three approaches to integrating Struts applications into the Spring framework, and then decide for yourself.


The approaches I demonstrate are all relatively simple to execute but they offer distinctly different advantages. So that you can fully understand each approach, I've created a separate working example for each one. See the Download section for the complete example source code. See Resources to download Struts MVC and the Spring framework.


What's so great about Spring?


Spring creator Rod Johnson took a critical eye to Java™ Enterprise software development and suggested that many enterprise issues could be resolved by the strategic use of the IOC pattern, also known as dependency injection. When Rod and a dedicated team of open-source developers put his theories into practice, the result was the Spring framework. In a nutshell, Spring is a lightweight container that makes it easy to wire objects together using an external XML configuration file. Each object can receive a reference to a dependent object by exposing a JavaBean property, leaving you with the simple task of "wiring them up" in an XML configuration file.










IOC and Spring

IOC is a design pattern that externalizes application logic so that it can be injected into client code rather than written into it. Combining IOC with the use of programming to interfaces, as the Spring framework does, yields an architecture that reduces the client's dependency on implementation-specific logic. See Resources for more on IOC and Spring.


Dependency injection is a powerful feature, but the Spring framework offers much more. Spring supports pluggable transaction managers to give you a broader range of choices for transaction handling. It integrates leading persistence frameworks while also offering a consistent exception hierarchy. Spring also provides a simple mechanism for applying aspect-oriented code against normal, object-oriented code.


Spring AOP lets you use interceptors to intercept application logic at one or more execution points. Interceptors are widely used for for logging because consolidating an application's logging logic in interceptors results in a more readable, functional code base. As you'll soon see, Spring AOP ships with its own interceptors for addressing cross-cutting concerns and also lets you write your own.
















Back to top



Integrating Struts and Spring


Like Struts, Spring can also function as an MVC implementation. Both frameworks have their merits and drawbacks, although most would agree that Struts is still king when it comes to MVC. Many development teams have learned to rely on Struts as the foundation for building quality software under strict deadlines. With so much momentum behind Struts, even development teams that would like to integrate features of the Spring framework don't want to switch to Spring MVC. The good news is that you don't have to. The Spring architecture allows you to connect Struts as your Web framework to Spring-based business and persistence layers. The end result is that you can have your cake and eat it too!


In the recipes that follow, you'll learn three ways to integrate Struts MVC into the Spring framework. I'll expose the cons of each recipe as well as its comparative advantages. Once you've seen all three in action, I'll show you an exciting application of the approach I like best.
















Back to top



Three little recipes


Each of the following integration techniques (or recipes) has its merits, as well as its own particular quirks. I'm partial to only one of them, but knowing them all will deepen your understanding of both Struts and Spring. It will also provide you with a broad range of options for dealing with various scenarios. The recipes are as follows:



  • Use Spring's ActionSupport class to integrate Struts
  • Override the Struts RequestProcessor with Spring's DelegatingRequestProcessor
  • Delegate Struts Action management to the Spring framework

Loading the application context


No matter which technique you use, you will need to use the Spring ContextLoaderPlugin to load the Spring application context for the Struts ActionServlet. Simply add the plug-in to your struts-config.xml file as you would any other plug-in, as shown here:






<plug-in className=
"org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property=
"contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>


As previously mentioned, you'll find the complete source for the three fully functional example applications in the Download section. Each example presents a different approach to combining Struts and Spring for a book-search application. You can follow the basics of the examples here, but download the applications to see all the nitty-gritty details!
















Back to top



Recipe 1. Use Spring's ActionSupport


Creating a Spring context manually is the most intuitive way to integrate Struts with Spring. To make it even easier, Spring offers a little help. The org.springframework.web.struts.ActionSupport class provides a getWebApplicationContext() method to easily obtain a Spring context. All you need to do is extend your action from Spring's ActionSupport instead of the Struts Action class, as shown in Listing 1:


Listing 1. Using ActionSupport to integrate Struts






package ca.nexcel.books.actions;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.springframework.context.ApplicationContext;
import org.springframework.web.struts.ActionSupport;

import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;

public class SearchSubmit extends ActionSupport { |(1)


public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

//the old fashion way
//BookService bookService = new BookServiceImpl();

ApplicationContext ctx =
getWebApplicationContext(); |(2)
BookService bookService =
(BookService) ctx.getBean("bookService"); |(3)

Book book = bookService.read(isbn.trim());

if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError
("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}

request.setAttribute("book", book);
return mapping.findForward("success");
}
}


Let's quickly consider what's happening here. At (1), I create an Action by extending from the Spring ActionSupport class rather than the Struts Action class. At (2), I use the getWebApplicationContext() method to obtain an ApplicationContext. To obtain the business service, I use the context obtained at (2) to look up a Spring bean at (3).


This technique is simple and easy to understand. Unfortunately, it couples the Struts action to the Spring framework. If you ever decide to replace Spring, you would have to rewrite the code. Moreover, because the Struts action isn't under Spring's control, it can't reap the benefits of Spring AOP. This technique may be useful when using multiple independent Spring contexts, but for the most part it's not as desirable a solution as the other two choices.
















Back to top



Recipe 2. Override the RequestProcessor


Decoupling Spring from the Struts action is a much smarter design choice. One way to do this is to override the Struts RequestProcessor processor with the org.springframework.web.struts.DelegatingRequestProcessor class, as shown in Listing 2:


Listing 2. Integration via Spring's DelegatingRequestProcessor






<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>

</form-beans>

<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>

<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="ca.nexcel.books.actions.SearchSubmit"
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>

</action-mappings>

<message-resources parameter="ApplicationResources"/>

<controller processorClass="org.springframework.web.struts.
DelegatingRequestProcessor"/> |(1)

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>


<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>

</struts-config>


Here, I've used the <controller> tag to override the default Struts RequestProcessor with the DelegatingRequestProcessor. My next step is to register the action in my Spring config file, as shown in Listing 3:


Listing 3. Registering an action in the Spring config file






<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit"> |(1)
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>
</beans>


Note that at (1), I've registered a bean using the name attribute to match the struts-config action mapping name. The SearchSubmit action exposes a JavaBean property, allowing Spring to populate the property at run time, as shown in Listing 4:


Listing 4. A Struts action with a JavaBean property






package ca.nexcel.books.actions;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;

public class SearchSubmit extends Action {

private BookService bookService;
public BookService getBookService() {
return bookService;
}

public void setBookService(BookService bookService) { | (1)
this.bookService = bookService;
}

public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

Book book = getBookService().read(isbn.trim()); |(2)

if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}

request.setAttribute("book", book);
return mapping.findForward("success");
}

}


In Listing 4, you can see how to build the Struts action. At (1), I create a JavaBean property. This property is automatically populated by the DelegatingRequestProcessor. This design protects the Struts action from knowing it's being managed by Spring while giving you all the benefits of Spring's action management framework. Because your Struts actions are oblivious to the existence of Spring, you can swap out Spring for some other inversion of control container without refactoring your Struts code.


While the DelegatingRequestProcessor approach is definitely better than the first one, it does have some problems. If you were using a different RequestProcessor, then you would need to integrate the Spring DelegatingRequestProcessor manually. The added code would become a maintenance hassle and would also reduce your application's flexibility going forward. Moreover, there has been some talk of replacing the Struts RequestProcessor with a chain of command. Such a change would negatively impact the longevity of this solution.
















Back to top



Recipe 3. Delegate action management to Spring


A much better solution is to delegate Struts action management to the Spring framework. You can do this by registering a proxy in the struts-config action mapping. The proxy is responsible for looking up the Struts action in the Spring context. Because the action is under Spring's control, it populates the action's JavaBean properties and leaves the door open to applying features such as Spring's AOP interceptors.


In Listing 5, the Action class is the same as it was in Listing 4. However, the struts-config is a little different:


Listing 5. The delegation method of Spring integration






<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>

</form-beans>

<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>

<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="org.springframework.web.struts.DelegatingActionProxy" |(1)
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>

</action-mappings>

<message-resources parameter="ApplicationResources"/>


<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>


<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>


</struts-config>


Listing 5 is a typical struts-config.xml file, except for one small difference. Instead of declaring the action's class name, it registers the name of Spring's proxy class, as shown at (1). The DelegatingActionProxy class uses the action mapping name to look up the action in the Spring context. This is the context that was declared with ContextLoaderPlugIn.


Registering a Struts action as a Spring bean is very straightforward, as shown in Listing 6. I simply create a bean using the name of the action mapping using the <bean> tag's name attribute (in this case, "/searchSubmit"). The action's JavaBean properties are populated like any Spring bean:


Listing 6. Register a Struts action in the Spring context






<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit">
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>

</beans>
















Back to top



The benefits of action delegation


The action-delegation solution is the best of the three. The Struts action has no knowledge of Spring and could be used in non-Spring applications without changing a single line of code. It's not at the mercy of a change to the RequestProcessor, and it can take advantage of Spring's AOP features.


The benefits of action delegation don't stop there, either. Once you have your Struts action under Spring's control, you can leverage Spring to give them more pizzazz. For example, without Spring, all Struts actions must be threadsafe. If you set the <bean> tag's singleton attribute to "false," however, your application will have a newly minted action object on every request. You might not need this feature, but it's nice to know you have it in your back pocket. You can also take advantage of Spring's lifecycle methods. For example, the <bean> tag's init-method attribute is used to run a method when the Struts action is instantiated. Similarly, the destroy-method attribute executes a method just before the bean is removed from the container. These methods are a great way to manage expensive objects in much the same way as the Servlet lifecycle does.
















Back to top



Intercepting Struts


As previously mentioned, one of the chief advantages of combining Struts and Spring, and doing it by delegating Struts actions to the Spring framework, is that you can apply Spring's AOP interceptors to your Struts actions. By applying Spring interceptors to Struts actions, you can tackle cross-cutting concerns with minimal effort.


Spring offers a few built-in interceptors, but I'll show you how to create your own and apply it to a Struts action. To use an interceptor, you need to do three things:



  1. Create the interceptor.
  2. Register it.
  3. Declare where it will intersect the code.

This is pretty simple stuff but also very powerful. For example, in Listing 7, I create a logging interceptor for a Struts action. This interceptor prints out a statement before every method call:


Listing 7. A simple logging interceptor






package ca.nexcel.books.interceptors;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class LoggingInterceptor implements MethodBeforeAdvice {

public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("logging before!");
}
}


This interceptor is very simple. The before() method is executed before every method in its intersection. In this case, it prints out a statement, but it could do anything you like. The next step is to register the interceptor in the Spring configuration file, shown in Listing 8:


Listing 8. Registering the interceptor in the Spring config file






<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit">
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>

<!-- Interceptors -->
<bean name="logger"
class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1)

<!-- AutoProxies -->
<bean name="loggingAutoProxy"
class="org.springframework.aop.framework.autoproxy.
BeanNameAutoProxyCreator"> |(2)
<property name="beanNames">
<value>/searchSubmit</valuesgt; |(3)
</property>
<property name="interceptorNames">
<list>
<value>logger</value> |(4)
</list>
</property>
</bean>

</beans>


As you've probably noticed, Listing 8 extends the application shown in Listing 6 to include an interceptor. Details are as follows:



  • At (1), I register the interceptor.
  • At (2), I create a bean name autoproxy describing how the interceptor is applied. There are other ways to define intersections, but this approach is common and easy to do.
  • At (3), I register the Struts action as the bean that will be intercepted. If you wanted to intersect other Struts actions, then you could simply create additional <value> tags under "beanNames."
  • At (4), when the interception occurs, I execute the name of the interceptor bean created at (1). All the interceptors listed here are applied against the "beanNames."

That's it! As this example shows, putting your Struts actions under control of the Spring framework opens up a whole new set of options for handling your Struts applications. In the case of this example, action delegation makes it easy to utilize Spring interceptors for better logging in Struts applications.
















Back to top



In conclusion


In this article, you learned three recipes for integrating Struts actions into the Spring framework. Using Spring's ActionSupport to integrate Struts (as I did in the first recipe) is quick and easy but couples your Struts actions to the Spring framework. If you ever needed to port the application to a different framework you would need to rewrite the code. The second solution of delegating the RequestProcessor cleverly decouples your code, but it doesn't necessarily scale well and may not last long if the Struts RequestProcessor is revised to a chain of command. The third approach is the best of the three: delegating Struts actions to the Spring framework results in decoupled code that lets you utilize Spring's features (such as logging interceptors) in your Struts applications.


Each of the three Struts-Spring integration recipes is realized as a complete working application. See the Download section to study them in detail.

















Back to top



Downloads























Description Name Size  Download method
ActionSupport sample code j-sr2-actionsupport.zip 5 MB FTP
RequestProcessor sample code j-sr2-requestprocessor.zip 5 MB FTP
Delegate sample code j-sr2-delegate.zip 5 MB FTP










Information about download methods Get Adobe® Reader®















Back to top



Resources

Learn


Get products and technologies


Discuss
















Back to top



About the author










George Franciscus is a Java Enterprise consultant and Struts authority. He is a coauthor of Manning's Struts Recipes and Struts in Action. George offers technical and management consulting services through nexcel.ca.


Posted by 아름프로

가정


id(아이디),password(비밀번호),idx(고유번호) 세개의 field를 갖는 test라는 테이블이 있고 이 안에는 72개의 데이터가 insert 되어 있다고 가정한다.


 


limit


mysql에서 지원하는 limit은 두개의 인자를 갖는다.





select * from test order by idx desc limit 5,10

위에서 보면 앞에 인자는 위치정보이면 뒤에 인자는 select에 의해 불러오는 데이터의 수량이다. 따라서 위의 쿼리문을 해석하면 test 테이블을 idx로 내림차순 정렬을 한 것을 6번째부터 15번째까지 10개의 데이터만을 불러오라는 내용이다.


 


다음의 쿼리문을 보자





select * from test order by idx desc limit 10

위의 내용은 다음과 같은 결과값을 갖는다.





select * from test order by idx desc limit 0, 10

즉 앞의 인자가 0일때는 생략이 가능하다는 것이다.


 


rownum


oracle에서 전체 테이블에서 특정 부분만을 가져올때는 rownum을 사용할 수 있다.


rownum은 가져오는 데이터의 수량으로 인식하면 된다.





select * from test where rownum<=5 order by idx desc

위의 쿼리문에 대한 해석은 test 테이블을 idx로 내림차순 정렬하여 첫번째부터 5번째까지 5개의 데이터만 불러오라는 내용이다.


 


여기서는 rownum이 단순히 수량만을 나타내는 것처럼 보이지만 실제는 위치정보도 포함할 수 있다.


 


다음을 보도록 하자.





select id,password, rownum from test where rownum<=5 order by idx desc

 



























id password idx
aaaa 0000 1
bbbb 1111 2
cccc 2222 3
dddd 3333 4
eeee 4444 5

 


위에서 처럼 rownum은 데이터 필드안에 삽입이 되서 보여 줄 수 있으며 이것을 통해 정렬도 가능하다.





1. select id, password, rownum as rnum from test where rownum<=5
order by rnum desc

 

2, select * from (select id, password, rownum as rnum from test where rownum<=5)
order by rnum desc

 



























id password idx
eeee 4444 5
dddd 3333 4
cccc 2222 3
bbbb 1111 2
aaaa 0000 1

 


위의 두개의 쿼리문은 동일한 결과값을 갖는다. 하지만 둘의 차이점은 첫번째 쿼리문은 order by를 rnum에게 할당함으로써 정렬하는 방법을 빼앗겼지만 두번째 쿼리문은 서브쿼리내에 정렬을 할 수가 있어 원하는 데이터를 가져오는데 훨씬 수월하다. 그렇다면 첫번째 방법으로는 완전히 불가능 한걸까? 아니다.


오라클에서 지원하는 힌트를 사용하면 가능하다.


먼저 인덱스를 생성한다.


 





create index test_indx on test(idx);

 


그리고 힌트를 사용하여 쿼리문을 만든다.


 





select /*+ index_desc(test test_indx) */ id, password, rownum as rnum from test
where rownum<=5 order by rnum desc

 


이렇게 하면 order by 부분은 hint에서 처리할 수 있다.


결론적으로 oracle의 rownum은 불러오는 데이터의 수량을 결정할 수 있으며 데이터의 안에서 글번호와 같은 위치에 대한 정보를 담아서 처리하는 기능을 지원해준다는 것이다.


 


top


mssql에서 지원하는 top은 위의 두개와 비교했을 때 정말 원초적인 기능이다. 단순히 불러오는 데이터의 수량만을 결정하는 것이기 때문이다.


top은 위치정보로 사용할 수도 없으며 이를 보완하고 도와줄 다른 어떤 기능도 없다. 계층형 게시판에서 원하는 데이터를 축출한다는 것은 아마도 가장 험난한 길을 인도하는 기능이다.


 





select top 5 * from test order by idx desc

 


top을 통해 원하는 부분만 가져올려면 여러번의 subquery를 작성해서 가져 와야 한다.

Posted by 아름프로
^^ 링크 참조
Posted by 아름프로

Introduction


This document discusses how you can set up a JDeveloper 10g workspace in order to use the multiple configuration features of Apache Struts. The use of multiple configuration files for the same application is a new feature added to Struts version 1.1 to help application developers better structure their sites and to ease the burden of maintenance for large applications. Multi configuration actually encompasses two different styles of usage:



  • Peer configurations - where one large application struts-config.xml file has been arbitrarily split up into two or more peer configuration files. The struts-example application is an example of this.
        <servlet>
          <servlet-name>action</servlet-name>
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
          <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
          </init-param>
          ...
        </servlet>

  • Sub-applications - where a more logical division of an application exists and where there is a master application configuration file and then one or more sub-application configuration files which are children of the main application and accessed at runtime using a path like syntax based on the sub-application name..
        <servlet>
          <servlet-name>action</servlet-name>
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
         <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
         </init-param>
         <init-param>
            <param-name>config/child1</param-name>
            <param-value>/WEB-INF/child1-config.xml</param-value>
         </init-param>
         <init-param>
            <param-name>config/child2</param-name>
            <param-value>/WEB-INF/child2-config.xml</param-value>
         </init-param>
          ...
        </servlet>

This document assumes that you are already familiar with the basic use of Struts, Struts multiconfig usage and of JDeveloper 10g as a Struts development environment.


JDeveloper 10g and Multiple Configurations


The reason for producing this document is to help developers around a restriction in the initial release of the JDeveloper 10g product. With this release of the product only one Struts page flow diagram can exist in each project. Attempting to use multiple page flow diagrams within a project can lead to unpredictable results and diagram corruption. As a result, applications which want to utilize peer or sub configurations will need to be organized in a special way to allow full page flow diagram functionality for each configuration file. The exact steps are outlined below, both for new applications and existing applications.


Creating a new Multiple Configuration Workspace


When creating a new multi config application you will need to plan in advance how many configuration files you will be using. In this example we'll use a total of three configurations, struts-config.xml as the parent configuration and two sub applications child1-config.xml and child2-config.xml. The principals of maintaining this projects in sync revolve around the use of a common HTML root and a common J2EE application name shared by all the projects. So lets step through the creation process for our workspace.



  1. Starting with an existing workspace or a newly created on if required, create three empty projects, in this case called parent, child1 and child2. It is best to create all of these under a common workspace directory, with each project in it's own sub-directory.
  2. At the same level as each of the project directories in the file system, create a public_html directory so you end up with a directory structure as follows:

    • Workspace directory

      • Parent
      • Child1
      • Child2
      • public_html

  3. Now edit the project properties of each project. Under the Common >> Input Paths node of the project properties, set the HTML Root Directory property to point to the common public_html directory
  4. Also in the project properties, choose the Common >> J2EE node and set each of the projects to use the same application and context root names e.g. multiApp and multiApp-context-root respectively. As you set the second and subsequent projects to share the same J2EE information you will receive a warning that another project shares the same name, you can ignore this warning and press Yes to continue.
  5. At this point save the workspace.
  6. Now you need to add Struts and your chosen view technology to the technology scope of each project. It is important that you do this to the parent project last.
    Again from the project properties dialog choose Common >> Technology Scope. Shuttle Struts and your view technology (e.g. JavaServer Pages (JSP) and Servlets) into the selected technologies list. When you OK the project properties dialog you will see a few files have been added to the project. Now save the Workspace. It is important to rename the struts-config.xml to the required name in each project as you go. So rename the xml file using File >> Rename, then save the workspace again and then continue to the next project.
  7. Once all of the projects have been set up for Struts you will need to edit the web.xml to define how each of the configurations will be used. As all of the projects share the same HTML root directory, they will also be sharing the same web.xml. As a result you have to be careful when updating web.xml and it is advisable to only ever update it from one place e.g. the parent project in this case. In this example we have three configurations, two of which are sub-applications. Here is the relevant part of the example web.xml file:
    <?xml version = '1.0' encoding = 'windows-1252'?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
       <description>Empty web.xml file for Web Application</description>
       <servlet>
         <servlet-name>action</servlet-name>
         <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
         <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
         </init-param>
         <init-param>
            <param-name>config/child1</param-name>
            <param-value>/WEB-INF/child1-config.xml</param-value>
         </init-param>
         <init-param>
            <param-name>config/child2</param-name>
            <param-value>/WEB-INF/child2-config.xml</param-value>
         </init-param>
    ...

    This Struts application is set up then with two sub applications which will be accessed through the use of /child1/ and /child2/ in the URI.
  8. Next you will need to flag to the projects that they are all dependent on each other - this is important to ensure that all of the files are correctly deployed when it comes to running your application and for resolving common files such as a shared ApplicationResources.properties file. Again this is done through the project properties dialog using the Common >> Dependencies node.
  9. Finally when it comes to running the application, ensure that you run the parent project first. Running an action on one of the child configurations before the parent can cause the parent not to run subsequently, although this can be corrected by changing the J2EE application and context root names in all of the projects and rerunning the parent project

Creating a Working Multiple Configuration Workspace from an Existing WAR file


If you have an existing code base or application which uses multiple configurations which you want to edit through JDeveloper you can import a WAR file of the application into an empty JDeveloper Workspace using the following steps :



  1. In the Application Navigator create an empty workspace, uncheck the Create New Empty Project checkbox if this is set.
  2. Select the workspace and choose File -> Import.
  3. In the Import dialog select the WAR file file you wish to consume. The Create Project from War File Wizard will appear.
  4. In step 1 define the project name as required and it's location. (Bear in mind that like starting from scratch you will be creating several projects to hold the various configurations).
  5. In step 2 of the wizard, define the name of the WAR file that you wish to import and define the location for the HTML root. As in the custom created projects, this HTML Root will be shared so it's probably a good idea to define it at the same level as your imported project, rather than under the imported project directory itself.
  6. Once the WAR file is imported expand the project WEB-INF folder. Examine the web.xml file to see which is the primary Struts configuration in the servlet definition, you'll want to keep this primary XML file in this project and move any others into projects of their own. So in the case of the struts-example.war that is shipped as a sample with Struts, and available in the /jakarta-struts/webapps directory under the JDeveloper distribution, the configuration setting in the web.xml looks like this:
      <!-- Action Servlet Configuration -->
      <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
        <init-param>
          <param-name>config</param-name>
          <param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>

  7. So in this case the struts-config.xml should remain in the import project and the struts-config-registration.xml removed from the import project using the remove button or the remove option on the file menu (not it needs to be removed from the project but not deleted from disk)..
  8. Create a new empty project for each of the extra configuration files.
    For each file:

    • In the project properties dialog select the Common -> Input Paths node of the tree and set the HTML Root Directory to the top level HTML Root directory you defined when using the WAR import wizard
    • The select the Common -> Dependencies node in the preferences dialog and check the dependency to the project imported from the WAR file.
    • Then select the Common -> J2EE node in the preferences dialog and set both the J2EE Web Application Name and the J2EE Web Context Root to the same values as used by the project imported from the WAR file. Ignore the unique name warning that pops up.
    • Then select the libraries node of the project properties tree and add JSP Runtime and Struts Runtime to the selected libraries list.
    • Choose Add to ... from the file menu to add the existing web.xml and secondary Struts configuration file to the new project
    • Back in the imported project edit the project properties and add this new project as a dependency of the imported one.

Once you have completed this process for each sub configuration you will be able to open a page flow diagram up in each project. You may choose to move JSP files etc to the relevant project that they apply to, however, there is no need to specifically do this as JDeveloper will work out where the files are if you try and drill down into them from the page flow diagram.


Running Child Application Page Flows


In the situation where you have sub-applications (such as in our example child1 and child2), you will be able to run Actions on the parent page flow diagram, or any peer application of the parent directly. However, if you attempt to run an Action from a sub application page flow diagram, it will fail with HTTP 400 (page cannot be found) error. This is because the URL that the runner will construct for the Action will not include the sub application path. For instance the url: http://localhost:8988/multiApp-context-root/child1_index.do may be generated rather than the correct http://localhost:8988/multiApp-context-root/child1/child1_index.do.


There are several approaches you can take to making it possible to run from a child application diagram. Take the situation where the parent project has a single entry point that the user always has to traverse, for instance a logon page. In this case using the context menu on the parent diagram set that page as the default run target for the parent diagram. This has the side effect of setting the Action unknown attribute to true for that action, so if you run from any of the other diagrams where an invalid Action URL is generated, Struts will redirect you to the application start point automatically.


Note that this will only work successfully if your Action names are unique across all of the sub applications.


However, you may wish to unit test just the flow within a particular sub application. If this is the case then you will need to adopt the following procedure.



  1. In the child configuration project, create a new JSP page called launch.jsp or similar.
  2. Edit this new page and add the following tag to the body:
    <jsp:forward page="/child1/child1_index.do"/>
    (Change the sub-application path and entry action as appropriate for your application)
  3. Edit the project properties for the child application project and in the Profiles >> Runner settings set the Default Run Target to your launch JSP and uncheck the Attempt to Run Active File Before Default checkbox.
  4. Now when you select run from the diagram this launch page will run, which in turn will construct the correct URL for your sub app.
  5. If you need to test different Actions within the child application, simply update the <jsp:forward> tag on this launch page as required.

Conclusion


Although the initial release of JDeveloper 10g does not seamlessly support multiple configuration Struts applications, with a little care it is entirely possible to use the product with such applications. In the next version of JDeveloper 10g it will be possible to dispense with the multiple project requirement, although structuring the workspace in this way may have benefits if multiple developers are working on different sections of the application.

Posted by 아름프로

w3c (http://www.w3c.org -> www.w3.org)
SOAP/XMLP
WSDL
Web Services



OASIS (http://www.oasis-open.org/home/index.php)
참조 : http://www.oasis-open.org/specs/index.php
<<ebXML관련>>
ebXML CPPA V2.0
ebXML MSG V2.0
ebXML RIM V2.0
ebXML RIM V3.0
ebXML RS V2.0
ebXML RS V3.0
UBL V1.0
UBL NDR V1.0


<<웹서비스관련>>
SAML V1.0
SAML V1.1 and
SAML V2.0
SPML V1.0 
UDDI V2 and
UDDI V3.0.2
WSDM-MOWS V1.0
WSDM-MUWS V1.0
WS-Reliability V1.1
WSRP V1.0
WSS SAML and REL Profiles
WSS V1.0

Posted by 아름프로

Why do developers need an Enterprise Service Bus?






Document options


















Set printer orientation to landscape mode

Print this page

Email this page

E-mail this page

Document options requiring JavaScript are not displayed






Rate this page











Help us improve this co

evel: Introductory

Bobby Woolf , WebSphere J2EE Consultant, IBM Software Services for WebSphere

26 Aug 2005

It's not just for architects: Using an Enterprise Service Bus, the foundation of a Service-Oriented Architecture (SOA), makes life easier for developers, too.

Introduction


Interesting applications rarely live in isolation; an application can't do much that is very useful without working with other applications. Service-Oriented Architecture takes the trend of integrating applications so that they can work together and accelerates it, breaking each application into parts that then must be integrated with each other. The SOA model -- service consumers invoking service providers -- may seem simple, but it introduces two significant problems:



  1. How does a consumer find the providers of the service it wants to invoke?
  2. How can a consumer invoke a service quickly and reliably, because the network is actually slow and unreliable?

It turns out there's a fairly straightforward answer to both these problems, an approach called the Enterprise Service Bus (ESB). An ESB makes service invocation simpler for both the consumer and the provider by handling all of the complexity in between. Not only does an ESB make it simpler for applications (or their parts) to invoke services, it also helps them transfer data and broadcast event notifications. An ESB's design embodies a number of established design patterns and standard specifications.


I wrote this article to help you, the developer, understand why an ESB is a useful and necessary part of application integration, including SOA. The article doesn't focus on definitions or products, but on the functions and capabilities an ESB implements for you so that you don't have to. It shows what an ESB does for you.










Back to top

Invoking services


To help you understand application integration and SOA, I'll start with how Web services work. Web services are only one approach you can use to implement a service invocation. They may not even be the best approach, but they are the most standardized approach available today, and they do help frame the design of what I'm trying to accomplish.


To begin, I must explain the terminology. A Web service is a lot like a function in procedural programming: it has a name, parameters, and a result. The name is a Uniform Resource Identifier (URI), which the Web services provider uses to make the Web service available as an endpoint. The Web services consumer uses the endpoint URI as the address for locating and invoking the Web service. The specific operation and parameters are contained in a request, which the consumer passes into the Web service when it invokes the endpoint. After performing the service, the endpoint passes a response back to the consumer, which indicates success (or an error) and contains the result of the service. So, a consumer invokes a provider's endpoint, passing in a request, and getting back a response.


The current definition of how to implement a Web service is the WS-I Basic Profile 1.1, which consists of SOAP 1.1 over HTTP 1.1 described by Web Services Description Language (WSDL) 1.1. (See Resources for a link to the specification itself.) With SOAP over HTTP, the consumer invokes a service using a SOAP request transported over HTTP in an HTTP request. The consumer blocks synchronously on the HTTP socket waiting for the HTTP response containing the SOAP response. The endpoint's API is described by its WSDL, a contract between the consumer and the provider.


Now that you understand the terminology, let's look at the communication choices a consumer has for invoking a service: synchronous or asynchronous.

Synchronous vs. asynchronous invocation


A consumer can implement a service invocation synchronously or asynchronously. From the consumer's point of view, the difference is this:



  • Synchronous – The consumer uses a single thread to invoke the service; the thread sends the request, blocks while the service is running, and waits for the response.
  • Asynchronous – The consumer uses a pair of threads to invoke the service; one thread sends the request, then a separate thread receives the response.

The terms synchronous and asynchronous are often confused with the terms sequential and concurrent. These latter terms have to do with the order that separate tasks must be performed, whereas synchronous and asynchronous have to do with the way a thread performs a single task, such as invoking a single service. A good way to understand the difference between synchronous and asynchronous invocation is to consider the consequences for crash recovery:



  • Synchronous – If the consumer crashes while blocking as the service runs, when it restarts it has no way of reconnecting to the invocation in progress, so the response is lost. The consumer must repeat the invocation and hope it doesn't crash this time.
  • Asynchronous – If the consumer crashes while waiting for the response after sending the request, when it restarts it can continue waiting for the response, so the response is not lost.

Crash recovery is not the only difference between synchronous and asynchronous invocation, but if you're trying to decide which style a particular invocation uses, looking at the way each handles crash recovery is usually a good way to tell.


Now that you understand the consumer's choices for service invocation communication style, take a look at the consumer's connectivity style choices for connecting to a provider. The consumer may choose from among the following communication styles:



  1. Synchronous direct invocation
  2. Synchronous brokered invocation
  3. Asynchronous brokered invocation

I will explain each style separately.


Synchronous direct invocation


The SOAP over HTTP style of invoking a Web service is said to be direct: Much like performing a function call, the consumer knows the address of the endpoint and invokes it directly. For the invocation to succeed, the Web service must be operational when the consumer invokes the endpoint and must respond before the consumer times out. If a Web service is deployed to a new location (such as a different Internet domain), the consumer must be made aware of the new URI for the endpoint. To deploy several providers of the same type of service, each provider's endpoint must be deployed to a different URI. To choose between the different service providers, the consumer must know each of their URIs.


For example, consider a simple Web service for getting a stock quote: The consumer passes in a stock symbol and gets back the stock's current price. This service might be provided by several different brokerage companies, each under a different Internet URL. Getting the URL for a Web service is a chicken-and-egg problem. If the consumer knew the location of the endpoint, it could ask the service what its address is, but that's the address the consumer would need so that it could ask for the address.


To get around this problem, the Universal Description Discovery and Integration (UDDI) specification describes a Web service that is a directory, like a phonebook, for locating other Web services. The idea is that the UDDI service is deployed to a well-known address the consumer will already know; then the consumer can use UDDI to find other Web services.


In the case of the stock quote service, the consumer knows the UDDI service's address, which in turn knows the stock quote services' addresses, as shown in Figure 1.


Figure 1: Direct invocation of a Web service
Direct invocation of a Web service

Figure 2 shows how the consumer uses the UDDI service to find the stock quote providers' endpoints and invoke one of them. The process works as follows:



  1. The consumer asks UDDI for a list of providers for a service.
  2. The consumer selects a provider's endpoint from the list returned by UDDI.
  3. The consumer invokes that endpoint.

Figure 2: Synchronous direct service invocation
Synchronous direct service invocation

Note that the algorithm for selecting a provider is completely up to the consumer; in this example, the consumer just chooses the first one in the list. A real implementation might be more sophisticated.


Notice also that because the service endpoints can change, every time the consumer wants to invoke the service, it should re-query UDDI to see if the providers' details have changed. Having to query UDDI for every service invocation greatly adds to the overhead of invoking the service, especially in the usual case where the providers' details haven't changed.


Synchronous brokered invocation


A shortcoming of the direct invocation approach is that the consumer must know the URI of the provider's endpoint to invoke the service. It uses UDDI as a directory to find that URI. If there are multiple providers, UDDI specifies multiple URIs, and the consumer must select from among them. If a provider changes its endpoint's URI, it must reregister with the UDDI server so that UDDI has the new URI, and then the consumer must re-query UDDI to get the new URI. In effect, this means that every time the consumer wants to invoke a service, it must query UDDI for the endpoint URIs and select from among them. This causes the consumer to waste a lot of effort repeatedly making UDDI lookups and selecting a provider. This approach also forces the consumer to somehow choose a provider from among a seemingly indistinguishable list.


One approach to simplify this problem is to introduce a broker to act as an intermediary for invoking the Web service. The consumer no longer invokes the service provider directly, but rather invokes a service proxy in the broker, which in turn invokes the service provider. The consumer needs to know the URI for the proxy's endpoint and so uses UDDI to find the address, but in this case, UDDI only returns a single URI, so the consumer doesn't have to choose. The consumer probably doesn't even realize that the endpoint is in a proxy; it just knows that it can use this URI for invoking the Web service. The broker coordinates the consumer with the service providers, as shown in Figure 3.


Figure 3: A synchronous enterprise service bus
A synchronous enterprise service bus

The proxy's URI should be stable: After the consumer uses UDDI to get the proxy's URI the first time it invokes the service, the consumer can reuse that URI for subsequent invocations (at least until the proxy stops working). Meanwhile, the proxy keeps track of the providers, their URIs (which may change between invocations), whether they're available (did the last invocation fail?), their load (how long did the last invocation take?), and so on. The proxy then takes the responsibility for choosing the best provider for each invocation, relieving the consumer of this responsibility. The consumer simply invokes the same proxy at the same address every time, and the proxy takes care of coordinating with the various providers.


Figure 4 shows how the consumer uses the broker to invoke the service, which works in the following way:



  1. The consumer asks UDDI for a list of providers for a service. The URI returned by UDDI is actually for the service proxy. UDDI will only return one URI, not several, because the broker only has one proxy for a particular service.
  2. The consumer invokes the service using the proxy's URI.
  3. The service proxy selects a service provider from its list of available providers.
  4. The service proxy invokes the selected provider's endpoint.

Figure 4: Synchronous brokered service invocation
Synchronous brokered service invocation

Notice that the effort of selecting the provider has moved from the consumer and is now encapsulated in the broker's proxy. This simplifies life for the consumer. Ultimately, the selection process the proxy uses may be no different than the process the consumer would have used. However, because the UDDI server and proxy are encapsulated within the broker, certain efficiencies can be more easily introduced, such as caching UDDI information in the proxy and having the UDDI server notify the proxy when the cached information becomes stale.


Note too that because the proxy's address is stable, the consumer doesn't have to query UDDI repeatedly, once per service invocation. Rather, the consumer only needs to query UDDI once and then can safely cache the proxy's address and use it to invoke the service repeatedly. This greatly lowers the overhead of invoking a service.


Asynchronous brokered invocation


A shortcoming of the synchronous approach is that the consumer must wait while the service is performed -- the consumer's thread must block while the service runs. If the service takes a long time to perform, the consumer may give up before it receives the response. When the consumer makes the request, if none of the service providers are running or if they're all overloaded, the consumer will not be able to wait. And as explained earlier, if the consumer crashes while blocking, even if it restarts the response will be lost and the invocation must be repeated.


A common solution to this problem is for the consumer to invoke the service asynchronously. With this approach, the consumer uses one thread to send the request and another to receive the response. This way the consumer doesn't have to block waiting for the response and can perform other work in the meantime. The consumer is therefore much less sensitive to how long it takes the provider to perform the service.


A broker that enables a consumer to invoke a Web service asynchronously is implemented using a messaging system that uses message queues for sending the request and receiving the response. Like a synchronous service proxy, the pair of message queues acts as a single address the consumer uses to invoke the service, regardless of how many providers may be listening, as shown in Figure 5.


Figure 5: An asynchronous enterprise service bus
An asynchronous enterprise service bus

This approach uses the Request-Reply pattern to invoke a Web service. Instead of HTTP as specified in WS-I BP 1.1, message queues now perform the transport. The SOAP request and response are the same as with WS-I BP, but they are now enclosed in messaging system messages.


Figure 6 shows how the consumer invokes the service asynchronously using a broker, which proceeds according to the following steps:



  1. The consumer sends the SOAP request as a message on the request queue. The consumer is now finished and can use that thread to perform other work.
  2. Each of the providers is a consumer on the request queue, which makes them competing consumers. The messaging system determines which provider is able to receive the message and ensures that only one provider receives the message. How this works specifically depends on the implementation of the messaging system.
  3. The winning provider receives the message from the request queue.
  4. The provider performs the service.
  5. The provider sends the SOAP response as a message on the reply queue. The provider is now finished and can use its thread to perform other work (such as waiting for another request).
  6. The consumer's listener thread receives the message containing the SOAP response.

Figure 6: Asynchronous brokered service invocation
Asynchronous brokered service invocation

Notice that the effort of selecting a provider is now encapsulated within the messaging system, simplifying life for the consumer. Notice also that if the consumer crashes after making the request, even if the response comes back in the meantime, the messaging system will save the response on the reply queue until the consumer starts up again.


Note as well that the consumer does not use UDDI to find the request and reply queues. Currently, there is no standard service for returning a pair of queue addresses, so the consumer must just know the addresses. The consumer is either hardcoded with the addresses or reads them from an external configuration file. In the future, either UDDI needs to be extended or a similar service specified that a consumer can query to discover the pair of queues for invoking a particular service.


Now you understand the connectivity style choices for service invocation. Let's look at additional integration capabilities that can also be helpful, then at how you develop an ESB that gives us these abilities.
















Back to top



Other integration capabilities


An ESB also gives you the opportunity to go beyond service invocation and integrate applications and parts of an SOA using other techniques. A service invocation is almost always a two-way operation, meaning that a request is sent from the consumer to the provider and a response is sent back in the other direction. Other integration techniques work as one-way operations, where a sender pushes information to the receiver but does not wait for a response; the receiver simply consumes the information without responding.


Data transfer


Sometimes an application simply wants to transfer data to another application without necessarily invoking a procedure in the receiver, and definitely without waiting for a result. This is a classic integration problem: One application has data that another one needs. The sender doesn't need to tell the receiver what to do with the data; it is just making the data available.


A service invocation can be used to transfer data, which is equivalent to invoking a setter method, but that's forcing the data transfer into the RPC paradigm. The data transfer is actually more like a file transfer: data is exported from the sender and imported to the receiver without the sender overtly directing the receiver as to what to do with the data. This is more akin to a document-style SOAP message than an RPC-style message.


Using an ESB for data transfer leverages its abilities to locate the receiver and transfer data reliably. The sender doesn't have to know how to find the receiver, it just has to know how to find the ESB and trust that it will find the receiver. The ESB is also responsible for transferring the data reliably. The sender can simply push the data into the ESB and know that it will be delivered.


For more information about the data transfer technique, see the Document Message pattern. (For more about this, see the book Enterprise Integration Patterns listed in Resources.)


Event notification


Sometimes a change occurs in one application that needs to be announced to other applications. For example, if a customer edits his address in an application, other applications with their own databases should be notified so they can update their records.


Again, one application can invoke a service on another application to inform it of a change, but there are three problems with this approach. The first two problems are the same as those with data transfer. First, a service invocation is too specific about what the receiver should do with the information, and second it tends to be two-way, forcing the sender to wait for a reply (even asynchronously) it doesn't really want.


The third and most significant problem with invoking a service for event notification is that service invocation is inherently one-to-one, consumer-to-provider, whereas event notification is inherently broadcast, one-to-many, to all interested receivers. Using service invocation, the sender would have to keep track of all interested receivers and invoke the service separately on each of them. This broadcasting of the notification is better left to the broker between the sender and the receivers.


Using an ESB for event notification leverages its abilities to keep a list of interested receivers and make sure the notification gets delivered to each one. It enables the sender to issue the notification just once and be assured that the notification will be delivered to all interested receivers, whoever those are. Because the operation is one-way, the sender can go about doing other work while the notifications are being delivered, and the notifications can be delivered concurrently.


For more information about the data transfer technique, see the Event Message pattern. (Again, see the book Enterprise Integration Patterns listed in Resources.)
















Back to top



Developing an Enterprise Service Bus


Now you know the difference between invoking a Web service in a provider directly as compared with doing so using a broker. You've also seen how the broker can enable the consumer to invoke the service synchronously or asynchronously.


The broker is often what has come to be called an ESB. So how does an ESB compare to already established designs and patterns?


Self-describing and discoverable


What distinguishes Web services from previous integration approaches is that a consumer can dynamically bind to the provider of a service. This works because of the following two main capabilities:



  • Self-describing – A Web service describes itself in a machine-readable way. Two or more providers of the same service are immediately recognizable, even though they may have very different implementations, because their declarative interfaces fit the same description.
  • Discoverable – Web services providers can be organized into machine-executable directories. A consumer can search such a directory to find a provider of a desired service.

These self-describing and discoverable capabilities of Web services are very different from previous integration approaches. With other approaches, interfaces were enforced at compile-time, which is also when consumers were bound to providers. Message formats were not expressed declaratively. They were implied by mutual agreement and not enforceable until a receiver failed to parse the structure created by the sender.


Self-describing services simplified integration by declaring interfaces that could be enforced. Dynamic discovery of services freed the consumer from being bound to a particular provider at a particular address, but the opportunity for run time discovery created its own problems. Should a consumer perform discovery of providers of a service once or repeatedly?


It has been difficult to resolve the tension between binding a consumer to a provider once-and-for-all at compile time versus potentially discovering a new provider with every invocation during run time. An ESB offers a third choice, a compromise enabling a consumer to dynamically bind to a service proxy just once and yet still be able to use multiple and future providers using the proxy.


Thus, an ESB not only makes services available so that consumers can invoke them, but it also offers consumers the ability to find the services programmatically.


Services gateway


The foundation for a synchronous ESB is what's known as a services gateway, which acts as a middleman between service consumers and providers to facilitate synchronous brokered invocations. It provides access to all known services and the service proxy for each of them. In this way, a gateway provides one-stop shopping for a consumer that wants to invoke any of the services in any of the providers the gateway brokers.


When the services the gateway coordinates are Web services, the services are self-describing. Each service declares its interface using WSDL, which consists of the following four parts:



  1. Port types -- The sets of operations performed by the Web service. A port type might be stockBrokerServices, with ports/operations like getQuote.
  2. Messages – The format of the requests and responses, such as getQuoteRequest (which contains a stock symbol) and getQuoteResponse (which contains a price).
  3. Types – The data types used by the Web service, such as symbol and price (or simply xs:string and xs:decimal).
  4. Bindings – The address for invoking the operation, such as http://stockbroker.example.com/getQuote.

Such a gateway's Web services -- or more specifically, its proxies for the services -- are also discoverable. The gateway provides this capability as a UDDI service, as illustrated earlier. To discover the address for invoking a service, a consumer queries the gateway's UDDI service for providers of the desired WSDL operation and gets back the binding for the gateway's proxy for that operation.


Message bus


At the foundation of an asynchronous enterprise service bus is an established pattern called a Message Bus, described in the book Enterprise Integration Patterns listed in Resources. A message bus is a collection of message channels (also known as a queue or topic) usually configured as request-reply channel pairs. Each pair represents a service that can be invoked by a consumer using the bus. The caller puts a request message on the request queue for the service and then (asynchronously) listens for the result on the reply queue. (The caller knows which result is the right one for its particular request because it has the right correlation identifier.)


The consumer invoking the service doesn't actually know who's providing the service. The service providers also connect to the message bus and listen for request messages. If there are multiple service providers, they actually compete with each other as competing consumers to be the one to consume a particular request. The messaging system that implements the message bus acts as a message dispatcher and distributes the request messages to the service providers, ideally optimizing this distribution somehow based on load balancing, network latency, and so forth. After a service provider receives a request, it performs the service and then puts the result in a message on the agreed-upon reply channel. So the provider and the consumer never directly know about each other's locations; they just know about the message bus and how to address the appropriate channels, and by sharing the same channels they can communicate.


This message bus is the gist of an ESB, and this is nothing new. Application integrators have been doing this for more than a decade using message queuing products like WebSphere® MQ and TIBCO Enterprise Message Service. Indeed, it's often said that if you are using enterprise messaging products, you have an ESB. IBM customers have been doing this for quite some time with WebSphere Business Integration Message Broker and WebSphere MQ.


So, is an ESB just a message bus? No, a message bus is definitely the foundation of an asynchronous ESB, but a full ESB is something more. An ESB has abilities message buses have always lacked: The aforementioned describing and discovery abilities.


A better message bus


So if a message bus is not a full ESB, then what else does an ESB do?


A shortcoming of the traditional message bus approach is that it's not self-describing. From the consumer's perspective, there are a whole lot of channels for invoking a whole lot of services. But which one is the right channel for invoking the service the consumer needs? The consumer can't just put a request on any request channel; it has to know the right channel to use to invoke the particular service it needs. Otherwise, it might end up buying an airline ticket when it wanted a book. Likewise, even after the consumer knows (somehow) which channel to use (and which channel to listen to for the reply), it then needs to know what format the data in the request needs to be (and what data format to expect for the reply).


As described earlier, WSDL solves this problem for synchronous Web services, and for the time being is the standard of choice for describing asynchronous services as well. The WSDL associated with a request channel would describe what service that channel provides as well as the format of the request message the consumer must provide. The WSDL would probably also specify the reply channel the caller should listen to for the reply and the format to expect for the reply message. In this way, a caller application can programmatically look at the pair of channels for invoking a service and know that they provide the desired service using the desired request and reply message formats.


Self-describing services channels lead to another issue, namely discovery, which synchronous Web services solve with UDDI. As shown earlier, a consumer asks a UDDI server for the address of a Web service provider, and the server replies with the URL for that provider. The consumer uses the URL to invoke the service.


An ESB needs a similar directory service, one with a UDDI-like API that a consumer can invoke to ask for the address of a service that implements the desired WSDL operation. The ESB replies with the address of the appropriate pair of request-reply channels. So an ESB consumer, like a UDDI consumer, needs to know nothing more than the following:



  1. The WSDL describing the service it wants to invoke
  2. The address of the ESB's directory service (which can probably be derived from the ESB's root address)

This is enough to locate a service's request and reply channels and start invoking the service. Furthermore, this directory service is just another service that the ESB provides, a master service for locating other services.


Synchronous or asynchronous?


Service consumers face an artificial choice between communication styles: synchronous or asynchronous. To solve this dilemma, many ESBs will support both synchronous and asynchronous services, and in fact may offer both invocation models for the same service. In this case, when a consumer asks for the address of a service, it can get two matches: one synchronous, the other asynchronous. The consumer can then choose the invocation model it likes best. Either way, the service performed is the same although the specific service provider instance may differ.


So an ESB is better than a traditional message bus because it also makes a service self-describing and provides a directory service for finding the other services. This is what the vendors of products for building ESBs are striving to deliver.
















Back to top



Conclusion


As you've seen, a service can be invoked in any of following three ways:



  1. Directly and synchronously
  2. Synchronously through a broker
  3. Asynchronously through a broker

An Enterprise Service Bus is a broker that supports synchronous and asynchronous service invocation. It also enables data transfer and event notification between applications. It helps consumers find providers and handles the details of communication between them.


A synchronous ESB is a services gateway that acts as a central coordinator of a variety of services. An asynchronous ESB is a message bus whose services also support the Web service capabilities of being self-describing and discoverable. Standards and patterns exist today for implementing a synchronous ESB and a message bus that is a simplified asynchronous ESB. Additional standards are needed for asynchronous ESBs to reach their full potential.









Back to top

Resources

Learn









Back to top

About the author


Photo of Bobby Woolf


Bobby Woolf is a WebSphere J2EE Consultant for IBM Software Services for WebSphere (ISSW). Bobby assists clients in developing applications for WebSphere Application Server using WebSphere Studio Application Developer. He is a co-author of Enterprise Integration Patterns and The Design Patterns Smalltalk Companion. He also has a blog on the IBM developerWorks Web site called J2EE in Practice. Bobby is a frequent conference speaker.

Posted by 아름프로

RTE 정리 잘된 곳

2005. 8. 30. 09:28
RTE의 개념은 2002년 10월에 Gartner Group에 의해 그 개념이 처음으로 제시되었으며, 지속적인 R&D활동을 통해 그 체계와 이론적 배경이 보강되어오고 있습니다. 이런 활동에 따라 Gartner Group에서는 RTE를 다음과 같이 정의하고 있습니다.
"RTE는 성공과 직결된 명시적 사건의 발생 즉시 그 근본 원인과 사건 자체를 파악, 모니터링, 분석함으로써 새로운 기회를 발굴하고 불행한 사태를 미연에 방지하며 핵심 비즈니스 프로세스의 지연을 최소화한다. 그리고 그렇게 확보한 정보를 활용하여 핵심 비즈니스 프로세스의 관리 및 이행 지연을 점진적으로 줄인다."

Posted by 아름프로
DBguide.net의 자료입니다.
Posted by 아름프로
아래의 내용처럼 기본적으로는 weblogic8.1에서는 JMS1.1 기반으로 사용이
불가능합니다.

1.1을 지원하고 있지는 않는 상황이고, 또한 공식적으로 1.1에 대한 지원에 대한
부분도 언급을 하고 있지는 않습니다.
문서상에 1.1을 받으라고는 나오지만 어떻게 해서 사용하라고하는 내용도 제공하지 않습니다.

포럼을 뒤져서 그나마 환경설정을 변경해서 편법적으로 사용한다는 글이 하나
있어서 테스트 해보니, 기본적인 기능에서는 처리가 되었기에 적어봅니다.

======================================

user_project의 프로젝트와 도메인의 start는 쫓아가보니 실행을 위한 환경설정 부분이 "C:\bea\weblogic81\common\bin" 의 commEnv.cmd 를 실행하면서 설정을 하게 되어있습니다.

이 파일을 열어보면
WEBLOGIC_CLASSPATH 라는 부분이 있습니다.
여기에 보면, weblogic.jar 파일이 등록되어져 있는 것을 보실 수 있습니다.
weblogic은 이 파일에 j2ee의 관련 api들을 한꺼번에 묶어서 제공을 합니다.
그렇기 때문에

이 파일의 앞쪽에 "http://java.sun.com/products/jms/docs.html"
여기에서 jms1.1 을 라이브러리 파일을 받은 후에 자신의 PC에 두고,
패스를 잡아주시면 됩니다.

예)
set WEBLOGIC_CLASSPATH=C:\Java\lib\jms.jar;%JAVA_HOME%\lib\tools.jar;%WL_HOME%\server\lib\weblogic_sp.jar;%WL_HOME%\server\lib\weblogic.jar

======================================
Posted by 아름프로
JMS Specification
WebLogic Server is fully compliant with version 1.0.2b of the JMS Specification, and can be used in production.

Note: As of the release date for WebLogic Server 8.1, Sun Microsystems has not certified any JMS implementation as being compliant with the version 1.1 JMS Specification. To use the WebLogic JMS implementation of the version 1.1 JMS Specification, use the link provided above to download the version 1.1 API documentation, JAR, and source files.

Posted by 아름프로
좋은 내용이라 링크가 아닌 여기로 남겨봅니다.
링크 참조하세요.

Abstract

JBoss is a free, open source J2EE implementation. Its architecture is highly modular and plug-in design. JBoss uses the industry standard Java Management eXtentions (JMX) to manage the JBoss components as well as provide services for EJB. Based on our previous research experience, we know there are great difference of performance and scalability among J2EE application servers. We believe the architecture design has an important role in determining the quality attributes such as performance and scalability. Analyzing and extracting architectural model from JBoss will provide us insights of its behavior and help us to build an accurate perdiction model on performance. In this project we analysis JBoss application server architecture especially on four susbsystems, JBoss EJB Container, JBossNS,JBossTX and JBossCMP. A reverse engineering tool is used to extract component/subsystem dependency from source code. Both the conceptual model and concrete model of the three JBoss subsystems are generated and the architectural styles used in JBoss design are discussed.

Posted by 아름프로

BLOG main image

카테고리

분류 전체보기 (539)
이야기방 (19)
토론/정보/사설 (16)
IBM Rational (9)
U-IT (0)
SOA/WS/ebXML (110)
개발방법론/모델링 (122)
J2SE (34)
J2EE (60)
DataBase (39)
Open Projects (30)
BP/표준화 (50)
Apache Projects (15)
Web/보안/OS (22)
Tools (7)
AJAX/WEB2.0 (1)
Linux/Unix (1)
영어 (0)
비공개방 (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2024/05   »
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

글 보관함

Total :
Today : Yesterday :