Programming/OSGi2011. 4. 12. 21:09
지난 SpringDM for OSGi Service에 서비스를 동적으로 관리하기 위한 추가 옵션이다.
SpringDM for OSGi Service <= Trackback 참조

<osgi:reference id="아이디입력" interface="인터페이스 입력">
<osgi:listener ref="서비스 추가시 컨트롤 하고 싶은 Bean의 아이디 입력" bind-method="서비스 추가시 컨트롤할 메서드명 입력" unbind-method="서비스 삭제시 컨트롤할 메서드명 입력" />
</osgi:reference>

위와 같이 서비스를 Bean으로 가져올 때 리스너를 추가해 주면 위에서 저장한 인터페이스의 서비스가 등록될 때
bind-method에 입력한 메서드가 동작하고  삭제 될 때 unbind-method에 입력한 메서드가 동작한다.
ref에 입력한 Bean 클래스에는 두 메서드를 추가해 주어야 하는데 다음과 같은 타입중 하나로 선언되어야한다.

public void 메서드명(ServiceType service, Map serviceProps);
public void 메서드명(ServiceType service, Dictionary serviceProps);
public void 메서드명(ServiceReference ref); 

참조: osgi:reference 뿐 아니라 osgi:set 이나 osgi:list에도 적용 가능하다.

다음 예를 보면 좀 더 이해가 편할 것이다. 
 
 <osgi:list id="Svcs" interface="kr.brian.api.Apis" cardinality="0..N">
<osgi:listener ref="svcsbean" bind-method="addSvcListener" unbind-method="removeSvcListener" />  
</osgi:list>
<bean id="svcsbean"
class="kr.brian.SvcListener">
</bean>

위와 같이 정의하고 클래스 kr.brain.SvcListener에 메서드 addSycListener와 removeSvcListener를 만들면 된다.
이때 주의할 점은 위에서 언급한 세가지 타입중 하나를 선택하여 파라미터를 정의해야 한다는 것이다. 
다음과 같이...

public void addSycListener(Apis service, Map serviceProps);
public void removeSvcListener(Apis service, Map serviceProps);


Posted by Brian B. Lee
Programming/OSGi2011. 2. 8. 11:24

일반 JAR 파일을 번들내에서만 사용 할 수 있는 방법에 대해 알아보자

1. 일단 JAR파일을 Workspace내의 폴더(New>folder=>lib)안에 넣는다.
2. Manifest 파일에 Bundle-Classpath에 저장 경로를 명시해 준다.
   ex)
   Manifest-Version : 1.0
   ...
   Bundle-Classpath: .,
     lib/log4j-1.2.15.jar
   위에서  주의 할 점은 기본 값의 첫 줄에 .,(번들 루트폴더)를 잡아주는 것이 중요하다.
3. 마지막으로 번들 Export를 위해 build.properties 파일에도 경로를 설정해 준다.
    ex)
   source.. = src/
   output..  = bin/
   bin.includes = META-INF/,\
                        .,\
                        lib/log4j-1.2.15.jar,\
                        log4j.properties
Posted by Brian B. Lee
Programming/OSGi2010. 12. 6. 11:20

Apache Felix Gogo 콘솔 확장하기

1. Felix Gogo

             Felix Gogo Apache에서 나온 OSGi framework를 위한 진보한 shell이다

2. 인터페이스

             Felix Gogo Console을 사용하기 위해 다음의 인터페이스를 구현하여 OSGi 서비스로 등록해야 한다. (서비스 등록방법은 지난 포스팅 참조) 하지만 인터페이스를 구현 한다고 해서 이 모든 메서드를 구현해 줄 필요는 없다. 자신이 원하는 메서드는 따로 만들어서 서비스 등록할 때 프로퍼티 파일에 참조해 주기만 하면 되기 때문이다.

public interface org.apache.felix.service.command.CommandSession {

Object execute(CharSequence commandline) throws Exception;

Object get(String name);

void put(String name, Object value);

    ...

}


Felix Gogo를 사요하기 위해 Maven에서 다음의 dependency를 추가해 줘야 한다.


            <dependency>

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

                      <artifactId>org.apache.felix.gogo.command</artifactId>

                      <version>0.6.0</version>

           </dependency>


 

3. 서비스 등록

             3-1. Console에서 실행할 메서드 구현

                          public class TestConsole implements CommandSession {

                                       public void test1(String x) {

                                                     System.out.println(x);

                                       }

                                       public void test2(String y) {

                                                     System.out.println(y);

                                       }

 

                                       //CommandSession를 구현하는 메서드

                                       @Override

                                       public Object execute(CharSequence arg0) throws Exception {

                                                    // TODO Auto-generated method stub

                                                     return null;

                                       }

                                       ….

                          }

             3-2. 서비스 등록

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

                           dict.put(CommandProcessor.COMMAND_SCOPE, "shell");

                           dict.put(CommandProcessor.COMMAND_FUNCTION, new String[] {"test1", "test2"});

                          context.registerService(org.apache.felix.service.command.CommandSession.class.getName(),

                             new TestConsole(context), dict);

 

위와 같이 인터페이스를 구현해서 서비스에 등록하면 프로퍼티로 넘겨준 dict에 담겨있는 메서드 test1, test2Console에서 실행할 수 있다. OSGi Console에서 help를 치면 shell:test1shell:test2가 등록되어 있는 것을 확인 할 수 있으며 test1 “Hello world” 라고 치면 Hello world OSGi Console에 찍히는 것을 확인 할 수있을 것이다.

객체 파라미터, 리턴 값에 대해서는 믿에 링크를 확인해 보길 바란다.
 

참고:

http://felix.apache.org/site/rfc-147-overview.html#RFC147Overview-StandardwaytoimplementandruncommandsforanyOSGi4.2framework

Posted by Brian B. Lee
Programming/OSGi2010. 12. 3. 10:56
본 내용은 실전 OSGi&SpringDM(위키북스) 책의 Chapter 7의 일부 내용입니다


OSGi 콘솔 확장하기 (for Eclipse Equinox Developers)

1. 인터페이스 추가

1.1 인터페이스

//org.eclipse.osgi.framework.console에 선언된 인터페이스

//Manifest Import-Package에 위의 인터페이스를 추가해 준다.

public interface CommandProvider {

           //콘솔창에서 help를 입력할 때 나오는 문장열

           public String getHelp();

}

 

1.2 구현체

//메소드 이름 앞에 “_”를 넣어줘야 자동으로 콘솔에 등록된다.

//inplements CommadProvider

public void _hello(CommandInterpreter ci) {

           System.out.println(“Hello “ + ci.nextArgument());

}

Posted by Brian B. Lee
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