Programming/OSGi2010. 10. 19. 10:11

밑에 스프링 사이트에서 jar파일 및 Dependency를 찾을수있습니다.

http://www.springsource.com/repository/app/;jsessionid=A431F38984691BE6F71E5849F17C46E0.jvm1

또한 이곳에서도 jar파일 및 Devpendency를 찾을 수 있다.

http://mvnrepository.com/

Posted by Brian B. Lee
Programming/OSGi2010. 10. 19. 09:24
http://java.dzone.com/articles/osgi-event-admin-with-spring-d 소스코드를 참조했음

1. SpringDMd을 사용

           1-1. 이벤트 핸들러로 이벤트 받기

                     Manifest.mf Import-Package org.osgi.service.event 추가

                     1-1-1. 인터페이스

                                public interface EventHandler {

                                          void handleEvnet(Event event);

                                }

                     1-1-2. 구현체

                                public class 클래스명 implements EventHandler {

                                          //인터페이스 구현체

                                          public void handleEvent(Event event) {

                                                     System.out.println("\r\n[Event Received] Topic : " + event.getTopic());

                                                     for(String key : event.getPropertyNames()){

                                                                System.out.println("\t[Property] " + key + " : " + event.getProperty(key));

                                                     }

                                          }

                                }

                     1-1-3. spring.xml                     

                                <osgi:service id="EventAdminServiceBean" ref="구현EventAdminBean"           interface="org.osgi.service.event.EventHandler">

                                          <osgi:service-properties>

                                                     <entry key="event.topics" value="Topic주소" />

                                          </osgi:service-properties>

                                </osgi:service>

                               

                                <bean id="구현EventAdminBean" class="구현EventAdmin경로" />

          

           1-2. 이벤트 보내기

                     1-2-1. 구현체

                                public class 클래스명 {

                                          private EventAdmin eventAdmin;

 

                                          @ServiceReference

                                          public void setEventAdmin(EventAdmin eventAdmin) {

                                                     this.eventAdmin = eventAdmin;

                                          }

                                         

                                          private String EVENT_QUEUE;

 

                                          public void setEVENT_QUEUE(String EVENT_QUEUE) {

                                                     this.EVENT_QUEUE = EVENT_QUEUE;

                                          }

                                         

                                          public void sender(){

                                                     Properties props = new Properties();

                                                     props.put("key", "value");

                                                     //동기 전송: sendEvent, 비동기 전송: postEvent

                                                     eventAdmin.sendEvent(new Event(EVENT_QUEUE, props));

                                          }

                                }

                    

                     1-2-2. spring.xml

                                <bean id="클래스Bean" class="클래스 경로" init-method="실행 메서드">

                                          <property name="EVENT_QUEUE" value="Topic주소" />

                                </bean>

          

                                <bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor" />

          

                     1-2-3. event를 보내기 위해 spring-osgi-annotation jar파일 필요

                                Maven을 사용한다면 dependency를 추가 하거나 아니며 spring-osgi-annotation jar파일이 필요

                                                     <dependency>

                                                                <groupId>org.springframework.osgi</groupId>

                                                               <artifactId>org.springframework.osgi.extensions.annotation</artifactId>

                                                                <version>1.2.1</version>

                                                     </dependency>

Posted by Brian B. Lee
Programming/OSGi2010. 10. 19. 09:17

본 내용은 실전 OSGi&SpringDM(위키북스) 책의 일부 내용입니다

1. SpringDM을 사용한 OSGi Service 구현
           Service를 좀더 편하게 사용하기 위해 SprigDM사용(SpringDM설치 방법 참조 Charter 11-p265)

           1-1. SpringDM xml서비스 등록

                     구현체 googleBean , 클래스 chapter12.google.Google를 인터페이스, 서비스 속성와 같이 서비스 등록

                    

                     <beans ... >

                                //구현체

                                <bean id="googleBean" class="chapter12.google.Google" />

                               

                                //서비스 등록                         

                                <osgi:service id="googleService" ranking="5" ref="googleBean">

                                          //인터페이스

                                          <osgi:interfaces>

                                                     <value>chapter04.searchengine.SearchEngine</value>

                                          </osgi:interfaces>

                                          //서비스 속성

                                          <osgi:service-properties>

                                                     <entry key="service.vendor" value="Google" />

                                                     <entry key="searchable" value="Text,Image,Code" />

                                          </osgi:service-properties>

                                </osgi:service>

                     </beans>

                    

           1-2. 서비스 실행

                     3-2-1. 서비스 실행 객체 얻기

                                //xml파일에서 주입받아 사용

                                private SearchEngine searhEngine;

                                public void setSearchEngine(SearchEngine searchEngine) {

                                          this.searcheEngine = searchEngien;

                                }

                     1-2-2. 서비스 주입을 위한 xml파일

                                <beans ...>

                                          //인터페이스를 통해 reference가져 옴

                                          <osgi:reference id="searchEngineSvc" interface="chapter04.searchengine.SearchEngine" />

                                          //<osgi:reference id="searchEngineSvc" interface="chapter04.searchengine.SearchEngine" cardinality="0..1" timeout="5000"/>

                                         

                                          //위의 reference를 통해 서비스 검색(서비스 없으면 5분 동안 해당 서비스 대기)

                                          <bean id="searchClient" class="chapter12.client.SearchClient" init-method="start">

                                                     <property name="searchEngine" ref="searchEngineSvc" />

                                          </bean>

                                </beans>

                     1-2-3. 복수 서비스 검색(더 많은 옵션은 chpater12-p321참조)

                                //xml파일에서 주입받아 사용

                                private List searhEngines;

                                public void setSearchEngines(List searchEngines) {

                                           this.searcheEngines = searchEngiens;

                                }

                               

                                //xml 파일

                                <beans ...>

                                          //인터페이스를 통해 reference가져 옴

                                          <osgi:List id="searchEngineSvc" interface="chapter04.searchengine.SearchEngine" />

                                         

                                          //위의 reference를 통해 서비스 검색(서비스 없으면 5분 동안 해당 서비스 대기)

                                          <bean id="searchClient" class="chapter12.client.SearchClient" init-method="start">

                                                     <property name="searchEngine" ref="searchEngineSvc" />

                                          </bean>

                                </beans>

3. OSGi Service를 구현한 jar파일

Maven을 사용한다면 dependency를 추가 하거나 아니며 OSGi Service를 구현 jar파일이 필요

<dependency>

<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
<version>3.1.200.v20071203</version>

</dependency>


Posted by Brian B. Lee
Programming/OSGi2010. 10. 18. 14:33
OSGi Log 서비스도 OSGi 서비스 중 하나이다 그래서 ServiceTracker를 사용하던 SpringDM을 이용하여 Bean로 서비스를
가져오던 서비스를 등록하고 가져오는 기능 중에 하나이다.

OSGi Log 서비스

1. OSGi Log 서비스

           Log4j를 직접 사용하는 것도 가능하지만, OSGi에서는 간단하면서도 확장이 쉽고 좀더 동적인 변경이 가능한

           OSGi Service 기반의 Log 메커니즘을 R1버전부터 제공하며 래퍼(Wpapper)와 같은 기능을 한다.

           사용자가 로그를 입력하기 위해 LogService ServiceTracker에서 객체를 받아와 log메서드로 log를 입력해주면

           로그를 받을 클래스에 LogListener 인터페이스를 구현 후 ServiceTracker에서 LogReaderService객체를 받아와 로그

 를 받을 클래스를 LogReaderService addLogListener(this) 해주면 받을 준비 끝이다.

           이제 로그를 받으면 되는데 LogListener 인터페이스의 구현체인 loged(LogEntry)에서 받은 logEntry타일에서 로그

 정보를 추출하면 된다.

           각각의 객체 설명은 밑에 인터페이스를 참조

           1-1. OSGi Log 서비스에서 사용하는 4개의 중요 인터페이스

                     1-1-1. LogService: LOG_ERROR=1, LOG_WARNING=2, LOG_INFO=3, LOG_DEBUG=4

                                                                log(int logLevel, String msg)

                                                                log(int logLevel, String msg, Throwable ex)

                                                                log(ServiceReference sr, int logLevel, String msg)

                                                                log(ServiceReference sr, int logLevel, String msg, Throwable ex)

                     1-1-2. LogEntry: LogService에 의해 생성되어 객체로 log메서드를 호출시 입력되는 부가 정보들과 메시지

                                                                getBundle() => 해당 로그메시지를 생성한 번들 객체 호출

                                                                getSErviceReference() => 해당 로그메세지와 관련있는

erviceReference 객체 반환(log메서드 호출시 입력한 것만)

                                                                getLevel() => 로그의 레벨을 가져옴

                                                                getMessage() => 로그의 문자열 가져옴

                                                                getException() => 해당 로그메세지와 관련있는 Throwable객체 반환

       (log메서드 호출시 입력한 것만)

                                                                getTime() => 로그메시지가 만들어진 시간 가져옴

                     1-1-3. LogReaderService: LogEntry객체의 리스트를 저장하여 사용자에게 리턴해주는 서비스

                                                                getLog() => 로그 메시지를 최근 순으로 가져온다.(이쿼녹스의 경우

     100개 로그 저장 객수와 레벨 설정은 Configuration속성에서 변경 가능)

                                                                addLogListener => LogReaderService에서 Listener 추가

                     1-1-5. LogListener: 로그를 리스닝 할 수 있는 인터페이스로 LogReaderService add해 주어야 로그를

    받을 수 있다.

                                                                logged(LogEntry) => LogReaderService LogEntry객체가 추가

되었을 때 호출

2. OSGi Log를 구현한 jar파일

Maven을 사용한다면 dependency를 추가 하거나 아니며 log구현 jar파일이 필요

<dependency>

<groupId>org.apache.felix</groupId>

<artifactId>org.apache.felix.log</artifactId>

<version>1.0.0</version>

</dependency>

Posted by Brian B. Lee
Programming/OSGi2010. 10. 18. 10:55
여러 번들에서 필요한 jar파일을 추가하기 이클립스에서 일반 jar파일을 OSGi화 해 보자

1. File => New => Plug-in from existing JAR archives(Plug-in Development 폴더에 들어있음) 선택
2. Plug-in from existing JAR archives 창이 따로 뜨면 Add External... 선택 후 추가할 jar파일 선택 => 하단에 Next 클릭
3. 새로운 Plugin에 대한 정보를 입력하는 창이 뜨면 Project name, Plug-in ID, Version, Name, Provider등을 입력하고 Target Platform에
    an OSGi framework 에서 Equinox 선택 후 하단 Finish 해주면 된다.

이제 jar 파일이 OSGi 화 되었으니 필요한 번들 Manifest파일의 Import-Package에 jar파일 명을 추가해 주면 된다.
Posted by Brian B. Lee
Programming/OSGi2010. 10. 18. 10:15


SpringDM
을 사용하여 POJO개발을 하면 BundleActivator BundleContext를 받을 수 없다. 하지만 SpringDM이 생성해주는 OSGi Application Context에는 기본적으로 bundleContext라는 Bean이 생성된다. 그러므로 BundleContext가 필요한 클래스에 BundleContextAware 인터페이스를 구현해 주면 BundleContext를 전단 받을 수 있다.

1. BundleContextAware
인터페이스

public interface BundleContextAware{

public void setBundleContext(BundleContext context);

}

2. BundleContext 얻기 

public calss 클래스명 implements BundleContextAware{

private BundleContext context;
public void setBundleContext(BundleContext context) {

this.context = context;

}

                     //위와 같이 BundeContextAware 인터페이스를 구현하면

                     //SpringDM이 자동으로 setBundleContext를 사용하여 Bean을 주입해줌

ServiceTracker tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);

}

 
Posted by Brian B. Lee
Programming/OSGi2010. 10. 18. 09:50

본 내용은 실전 OSGi&SpringDM(위키북스) 책의 일부 내용입니다

Event Admin 서비스 사용

1. 기본 계념

           화이트보드 패턴을 이용하여 이벤트 메시지를 전달 한다.

           1-1. Event Object 속성

                     //이벤트 필터링을 이름 같은 것(일반적으로 kr/bit/uhealth 와 같이 계층구조를 가짐)

                     String Topic

                     //이벤트에 대한 추가 속성(속성 종류는 charter5-p114 참조)

                     Hashtable properties

          

2. Event Admin 구현

           2-2. 이벤트 핸들러로 이벤트 받기

                     Manifest.mf Import-Package org.osgi.service.event 추가

                     2-2-1. 인터페이스

                                public interface EventHandler {

                                          void handleEvnet(Event event);

                                }

                      2-2-2. 구현체

                                public class Activator implements BundleActivator, EventHandler {

                                          //모든 이벤트 받음

                                          final static String[] topics = new String[]{"*"};

                                         

                                          public void start(BundleContext context) throws Exception {

                                                     Dictionary<String, Object> prop = new Hashtable<String,Object>();

                                                     prop.put(EventContants.EVENT_TOPIC, topics);

                                                    

                                                     context.registerService(EventHandler.class.getName(), this, prop);

                                          }

                                         

                                          public void stop(BundleContext context) throws Exception {

                                                     ...

                                          }

                                          

                                          //인터페이스 구현체

                                          public void handleEvent(Event event) {

                                                     System.out.println("\r\n[Event Received] Topic : " + event.getTopic());

                                                     for(String key : event.getPropertyNames()){

                                                                System.out.println("\t[Property] " + key + " : " + event.getProperty(key));

                                                     }

                                          }

                                }

                               

                     2-2-3. 이벤트 필터링

                                //모든 이벤트 받기

                                final static String[] topics = new String[]{"*"};

                                //세부항목 이벤트 받기

                                final static String[] topics = new String[]{"org/osgi/framework/ServiceEvent/*"};

                                //세부 선택항목 이벤트 받기

                                final static String[] topics = new String[]{"org/osgi/framework/ServiceEvent/REGISTERED", "org/osgi/framework/ServiceEvent/STARTED"};

                                //그 밖에 필터 방법 http://www.ietf.org/rfc/rfc2254.txt 참조

          

           2-3. 이벤트 보내기

                     ServiceTracker tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);

                    

                     tracker.open();

                    

                     Properties props = new Properties();

                     props.put("key", "value");

                     EventAdmin ea = (EventAdmin) tracker.getService();

                     if(ea != null) {

                                //동기 전송: sendEvent, 비동기 전송: postEvent

                                ea.sendEvent(new Event("com/foo/bar", props));                          

                     }

3. EventAdmin을 구현한 jar파일

Maven을 사용한다면 dependency를 추가 하거나 아니며 EventAdmin을 구현 jar파일이 필요

<dependency>

<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.eventadmin</artifactId>
<version>1.0.0</version>

</dependency>

Posted by Brian B. Lee
Programming/OSGi2010. 10. 18. 09:44

 
본 내용은 실전 OSGi&SpringDM(위키북스) 책의 일부 내용입니다.

OSGi 서비스 사용

1. 서비스 구현을 위한 3요소 (chapter 4-p69)

 SGi 서비스 등록을 위해서는 해당 서비스 객체의 인터페이스, 인터페이스 구현체, 서비스 속성 Dictionary가 필요하다. 그리고 기본적으로 모든 구현 번들 Manifest.mf Import-Package에는 인터페이스 패키지(믿의 예에선 SearchEngine  인터페이스)를 추가해 주어야하며 인터페이스 패키지는 Manifest.mf에 Export-Package되어야 한다.

           1-1. 서비스 3요소

                     1-1-1. 인터페이스

                                public interface SearchEngine {

                                          List<String> search(String query);

                                          List<String> searchImage(String query);

                                }

                     1-1-2. 구현체

                                public Google implements SearchEngine {

                                          List<String> search(String query) {

                                                     ...

                                          }

                                          List<String> searchImage(String query) {

                                                     ...

                                          }

                                }

                                public Naver implements SearchEngine {

                                          List<String> search(String query) {

                                                     ...

                                          }

                                          List<String> searchImage(String query) {

                                                     ...

                                          }

                                }

                     1-1-3. 서비스 속성

                                Dictionary props = new Properties();

 

                                props.put(org.osgi.framework.constants.SERVICE_VENDOR, "Google");

                                props.put("searchable", "Text,Image");

         //서비스를 등록할 때 개발자가 지정할 수 있는 랭킹 값으로, 만약 같은 인터페이스에 대해  
         //여러 개의 서비스 구현체가 있다면 이 랭킹값이 큰 순으로 우선순위를 가진다.

         //기본값은 0이다. 만약 랭킹값이 같다면 id값이 작은 것이 더 높은 우선순위를 가진다.

                                props.put(org.osgi.framework.Constants.SERVICE_RANKING, 5);

                                         

2. 서비스 구현

           2-1. 서비스 등록 구현

                     public class Activator implements BundleActivator {

//인터페이스

                                private SearchEngine service;

//서비스에 대한 접근자인 ServiceReference를 읽어오거나, Service의 등록을 해지할 때 사용

//, 서비스 등록은 Bundlecontext.registerService가 하지만 서비스 해지는 ServiceRegistratio 을 통해서만 가능

                                private ServiceRegistration registration;

                               

                                public class Activator implements BundleActivator {

//서비스 속성

                                          Dictionary props = new Properties();

                                          props.put(org.osgi.framework.Constants.SERVICE_VENDOR, "Google");

                                          props.put("searchable", "Text,Image");

                                          props.put(org.osgi.framework.Constants.SERVICE_RANKING, 5);

                                         

//인터페이스 구현체

                                          service = new Google();

                                         

//서비스 등록
//context.registerService(인터페이스,구현체,서비스속성)                            

                                          registration = context.registerService(SearchEnglish.class.getName(), service, props);

 //여러게 서비스 등록

 //bundlecontext.registerService(String[] clazzes, Object service, Dictionary properties);

                                }

                               

                                public void stop(BundleContext context) throws Exception {

 //서비스 해지(꼭하지 않아도 됨)

                                          registration.unregister();

                                }

                     }

          

           2-2. 서비스 실행

                     2-2-1. 서비스 정보를 가져오는 ServiceReference 인터페이스

 //BundleContext.getServiceReference(String interfaceName);

 //BundleContext.getService(ServiceReference refenece);

 //BundleContext.getServiceReference에서 서비스레퍼런스 정보를 객체로 가져와

 //이 객체를 통해 BundleContext.getServiceReference함수로 서비스를 가져올 수 있다.

                                public interface ServiceReference extends Comparable {

 //속성 값을 읽어 온다.

                                          public Object getProperty(String key);

 //속성의 키 값을 배열로 읽어온다.

                                          public Stiring[] getPropertyKeys();

 //이 서비스를 등록한 번들 객체를 리턴한다. 만약 서비스가 unregister 되었다면
 
//null을 리턴한다.

                                          public Bundle getBundle();

 //이 서비스를 사용하는 번들의 배열을 리턴

                                          public Bundle[] getUsingBundles();

                                }

                     2-2-2. 서비스 실행 구현

                                public class ClientActivator implements BundleActivator{

                                          ServiceReference reference;

                                          SearchEngine engine;

                                          public void start(BundleContext context) throws Exception {

 //ServiceReference객체를 가져옴

                                                     reference = context.getServiceReference(SearchEngine.class.getName());

 //ServiceReference객체를 통해 서비스를 가져옴

                                                     engine = (SearchEngine) context.getService(reference);

                                                    

 //검색엔진을 사용하여 검색기능 호출

                                                     List result = engine.search("query string");

                                          }

                                         

                                          public void stop(BundleContext context) throws Exception{

                                                     context.ungetService(reference);

                                                     engine = null;

                                          }

                                }

          

           2-3. 서비스 검색

                     2-3-1. SerivceTracker

                                2-2-2와 같이 서비스를 가져오면 OSGi 동적 환경에서 서비스가 언제 존재 할지 모르기 때문에 서비스를 기다려야 한다. 이런 서비스를 찾고 기다리기 위해 ServiceTracker가 필요하다.

                                2-3-1-1. ServiceTracker 메서드

//세 개의 생성자를 가지고 있음 ServiceTrackerCustomizer는 추적하는 방식을 개발자가 
//원하는데로 변경(자세한 설명 책에 없음)

                                          ServiceTracker(BundleContext, ServiceReference, ServiceTrackerCustomizer)

                                          ServiceTracker(BundleContext, String, ServiceTrackerCustomizer)

                                          ServiceTracker(BundleContext, Filter, ServiceTrackerCustomizer)

//ServiceTracker 사용전 open() 서비스 사용 끝난 후 close()

                                          open(), close()

//서비스 리턴 getService()는 랭크값이 크고 ID가 가장 작은 서비스, getServices()는 해당 
//모든 서비스 리턴

                                          getService(), getServices()

//해당 ServiceReference또는 그 배열 리턴

                                          getServiceReference(), getServiceReferences()

//timeout시간동안 서비스 검색 후 서비스 반환, 0일경우 무한 루프(데드락이 걸릴수있음 스레드 사용 권장)

                                          waitForService(timeout)                        

                     2-3-2. ServiceTracker 구현

                                public void run() {

//context는 스레드 인자값으로 값음, ServiceTrackerCustomizer null

                                          ServiceTracker tracker = new ServiceTracker(context, SearchEngine.class.getName(), null);

                                         

                                          track.open();

                                         

                                          SearchEngine engine;

                                          try {

//파라미터 0은 무한 검색

                                                     engine = (SearchEngine) tracker.waitForService(0);

                                                    

//서비스 실행

                                                     List results = engine.search("query string");

                                                     ...

                                          } catch (InterruptedException e) {

                                                     e.printStackTrace();

                                          }

                                         

                                          tracker.close();

                                }

                               

3. OSGi Service를 구현한 jar파일

Maven을 사용한다면 dependency를 추가 하거나 아니며 OSGi Service를 구현 jar파일이 필요

<dependency>

<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
<version>3.1.200.v20071203</version>

</dependency>

Posted by Brian B. Lee