栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

osgi:使用ServiceFactories?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

osgi:使用ServiceFactories?

这是一个使用ComponentFactory的示例,该示例应符合您的需求(并包含一个简单的集成测试以帮助解决您的其他问题)。免责声明;举例来说,代码编写得不好。

一些服务接口:

package net.earcam.example.servicecomponent;public interface EchoService {    String REPEAT_PARAMETER = "repeat";    String FACTORY_DS = "echo.factory";    String NAME_DS = "echo";    String echo(String message);}

和:

package net.earcam.example.servicecomponent;public interface SequenceService {    long next();}

然后实现:

import static net.earcam.example.servicecomponent.EchoService.FACTORY_DS;import static net.earcam.example.servicecomponent.EchoService.NAME_DS;import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY;import static org.apache.felix.scr.annotations.ReferencePolicy.DYNAMIC;import net.earcam.example.servicecomponent.EchoService;import net.earcam.example.servicecomponent.SequenceService;import org.apache.felix.scr.annotations.Activate;import org.apache.felix.scr.annotations.Component;import org.apache.felix.scr.annotations.Reference;import org.osgi.service.component.ComponentContext;@Component(factory = FACTORY_DS, name = NAME_DS)public class EchoServiceImp implements EchoService {    @Reference(cardinality = MANDATORY_UNARY, policy = DYNAMIC)    private SequenceService sequencer = null;    private transient int repeat = 1;    @Activateprotected void activate(final ComponentContext componentContext){    repeat = Integer.parseInt(componentContext.getProperties().get(REPEAT_PARAMETER).toString());}@Overridepublic String echo(final String message){    StringBuilder stringBuilder = new StringBuilder();    for(int i = 0; i < repeat; i++) {        addEchoElement(stringBuilder, message);    }    return stringBuilder.toString();}private void addEchoElement(final StringBuilder stringBuilder, final String message) {    stringBuilder.append(sequencer.next()).append(' ').append(message).append("n");        }protected void unbindSequencer(){    sequencer = null;}protected void bindSequencer(final SequenceService sequencer){    this.sequencer = sequencer;}

}

和:

package net.earcam.example.servicecomponent.internal;import java.util.concurrent.atomic.AtomicLong;import net.earcam.example.servicecomponent.SequenceService;import org.apache.felix.scr.annotations.Activate;import org.apache.felix.scr.annotations.Component;import org.apache.felix.scr.annotations.Deactivate;import org.apache.felix.scr.annotations.Service;@Component@Servicepublic class SequenceServiceImp implements SequenceService {    private AtomicLong sequence;    @Override    public long next()    {        return sequence.incrementAndGet();    }    @Activate    protected void activate()    {        sequence = new AtomicLong();    }    @Deactivate    protected void deactivate()    {        sequence = null;    }}

可以驱动整个过程的集成测试(请注意;有一种主要方法,因此您可以在启动/停止分发包等时运行它)。

package net.earcam.example.servicecomponent.test;import static org.ops4j.pax.exam.CoreOptions.*;import static org.ops4j.pax.exam.OptionUtils.combine;import static org.ops4j.pax.exam.spi.container.PaxExamRuntime.createContainer;import static org.ops4j.pax.exam.spi.container.PaxExamRuntime.createTestSystem;import java.io.File;import java.io.FileFilter;import java.io.FileNotFoundException;import java.util.Dictionary;import java.util.Hashtable;import java.util.regex.Matcher;import java.util.regex.Pattern;import net.earcam.example.servicecomponent.EchoService;import net.earcam.example.servicecomponent.SequenceService;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.ops4j.pax.exam.Option;import org.ops4j.pax.exam.junit.Configuration;import org.ops4j.pax.exam.junit.ExamReactorStrategy;import org.ops4j.pax.exam.junit.JUnit4TestRunner;import org.ops4j.pax.exam.spi.reactors.EagerSingleStagedReactorFactory;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import org.osgi.service.component.ComponentFactory;import org.osgi.service.component.ComponentInstance;@ExamReactorStrategy(EagerSingleStagedReactorFactory.class)@RunWith(JUnit4TestRunner.class)public class EchoServiceIntegrationTest {    public static void main(String[] args) {        try { createContainer(         createTestSystem(      combine(   new EchoServiceIntegrationTest().config(),    profile("gogo"))         )).start();        } catch(Throwable t) { t.printStackTrace();        }    }    @Configuration    public Option[] config()    {        return options(     felix(),     equinox(),     junitBundles(),     systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("TRACE"),     mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.scr").versionAsInProject(),     bundle("file:" + findFileInCurrentDirectoryAndBelow(  Pattern.compile("net\.earcam\.example\.servicecomponent\-[\.\d]+(\-SNAPSHOT)?\.[wj]ar")))        );    }    @Test    public void bundleContextIsAvailable(BundleContext context)    {        Assert.assertNotNull("PAX Exam BundleContext available", context);    }    @Test    public void sequenceServiceIsAvailable(BundleContext context)    {        Assert.assertNotNull("SequenceService available", fetchService(context, SequenceService.class));    }    @Test    public void serviceResponseContainsThreeEchos(BundleContext context) throws Exception    {        final String message = "message";        final String expected = "1 " + message + "n2 " + message + "n3 " + message + "n";        ComponentFactory factory = fetchComponentFactory(context, EchoService.FACTORY_DS);        Dictionary<String, String> properties = new Hashtable<String, String>();        properties.put(EchoService.REPEAT_PARAMETER, "3");        ComponentInstance instance = factory.newInstance(properties);        EchoService service = (EchoService) instance.getInstance();        String actual = service.echo(message);        Assert.assertEquals("Expected response", expected, actual);    }    private ComponentFactory fetchComponentFactory(BundleContext context, String componentFactoryId) throws Exception    {        String filter = "(component.factory=" + componentFactoryId + ")";        ServiceReference[] references = context.getServiceReferences(ComponentFactory.class.getCanonicalName(), filter);        return (references.length) == 0 ?  null : (ComponentFactory) context.getService(references[0]);    }    private <T> T fetchService(BundleContext context, Class<T> clazz)    {        ServiceReference reference = context.getServiceReference(clazz.getCanonicalName());        @SuppressWarnings("unchecked")        T service = (T) context.getService(reference);        return service;    }    private String findFileInCurrentDirectoryAndBelow(final Pattern filePattern) {        FileFilter filter = new FileFilter() { @Override public boolean accept(File pathname) {     Matcher matcher = filePattern.matcher(pathname.getName());     return (matcher.matches()); }        };        return findFile(new File("."), filter, filePattern);    }    private String findFile(File directory, FileFilter filter, Pattern filePattern) {        File[] matches = directory.listFiles(filter);        if(matches != null && matches.length > 0) { return matches[0].getAbsolutePath();        }        File[] subdirs = directory.listFiles(new FileFilter() { @Override public boolean accept(File pathname) {     return pathname.isDirectory(); }        });        for(final File subdir : subdirs) { String found = findFile(subdir, filter, filePattern); if(!"".equals(found)) {     return found; }        }        throw new RuntimeException(new FileNotFoundException("No match for pattern: " + filePattern.pattern()));    }}

这是Maven Pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.earcam</groupId>    <artifactId>net.earcam.example.servicecomponent</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>jar</packaging>    <properties>        <version.java.source>1.6</version.java.source>        <version.java.target>1.6</version.java.target>        <version.osgi>4.2.0</version.osgi>        <version.paxexam>2.1.0</version.paxexam>        <version.paxrunner>1.7.4</version.paxrunner>        <version.cometd>2.3.1</version.cometd>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    </properties>    <dependencies>        <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> <version>${version.osgi}</version> <scope>provided</scope>        </dependency>        <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>${version.osgi}</version> <scope>provided</scope>        </dependency>        <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr.annotations</artifactId> <version>1.4.0</version> <scope>provided</scope>        </dependency>        <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3.RC2</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.jmock</groupId> <artifactId>jmock-junit4</artifactId> <version>2.5.1</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.1</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-junit4</artifactId> <version>${version.paxexam}</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-container-paxrunner</artifactId> <version>${version.paxexam}</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-link-assembly</artifactId> <version>${version.paxexam}</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-testforge</artifactId> <version>${version.paxexam}</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.ops4j.pax.runner</groupId> <artifactId>pax-runner-no-jcl</artifactId> <version>${version.paxrunner}</version> <scope>test</scope>        </dependency>        <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr</artifactId> <version>1.6.0</version> <scope>test</scope>        </dependency>    </dependencies>    <build>        <plugins> <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-compiler-plugin</artifactId>     <version>2.3.2</version>     <configuration>         <source>${version.java.source}</source>         <target>${version.java.target}</target>         <encoding>${project.build.sourceEncoding}</encoding>     </configuration> </plugin> <plugin>     <!-- Unit Tests -->     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-surefire-plugin</artifactId>     <version>2.8.1</version>     <executions>         <execution>  <goals>      <goal>test</goal>  </goals>         </execution>     </executions>     <configuration>         <excludes>  <exclude>***IntegrationTest.java</include>         </includes>     </configuration> </plugin> <plugin>     <groupId>org.ops4j.pax.exam</groupId>     <artifactId>maven-paxexam-plugin</artifactId>     <version>1.2.3</version>     <executions>         <execution>  <id>generate-config</id>  <goals>      <goal>generate-depends-file</goal>  </goals>         </execution>     </executions> </plugin> <plugin>     <!-- Process the DS annotations -->     <groupId>org.apache.felix</groupId>     <artifactId>maven-scr-plugin</artifactId>     <version>1.6.0</version>     <executions>         <execution>  <id>generate-scr-descriptor</id>  <goals>      <goal>scr</goal>  </goals>  <phase>process-classes</phase>  <configuration>      <strictMode>true</strictMode>      <outputDirectory>${project.build.outputDirectory}/</outputDirectory>  </configuration>         </execution>     </executions> </plugin> <plugin>     <!-- Generate OSGi bundle MAINFEST.MF entries -->     <groupId>org.apache.felix</groupId>     <artifactId>maven-bundle-plugin</artifactId>     <version>2.3.4</version>     <extensions>true</extensions>     <configuration>         <supportedProjectTypes>  <supportedProjectType>jar</supportedProjectType>         </supportedProjectTypes>         <instructions>  <Bundle-Vendor>earcam</Bundle-Vendor>  <Service-Component>OSGI-INF/serviceComponents.xml</Service-Component>  <!-- PAX mangles this, it uses the name of the project for the symbolicname       of test bundle? <Bundle-SymbolicName>${project.name}</Bundle-SymbolicName> -->  <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>  <Bundle-Version>${project.version}</Bundle-Version>  <Export-Package>!${project.artifactId}.internal,${project.artifactId}.*</Export-Package>  <import-Package>*</import-Package>         </instructions>     </configuration>     <executions>         <execution>  <id>bundle-manifest</id>  <phase>process-classes</phase>  <goals>      <goal>manifest</goal>  </goals>         </execution>     </executions> </plugin> <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-jar-plugin</artifactId>     <version>2.3.1</version>     <configuration>         <archive>  <manifestFile>${project.build.outputDirectory}/meta-INF/MANIFEST.MF</manifestFile>         </archive>     </configuration> </plugin>        </plugins>    </build></project>

需要注意的几件事;我喜欢我的集成模块内的集成测试,这样,如果集成测试成功, mvn clean install部署 就会失败-
但是常见的情况是,对于所有集成测试,只有一个集成模块的项目就会出现。这说明了

findFileInCurrentDirectoryAndBelow(Patternpattern)
用于在目标目录中定位当前模块捆绑包的难看方法,还说明了maven-bundle-plugin和maven-scr-
plugin插件的非标准设置。

同样,Pax-
Exam获取依赖项的方式还要求您对依赖项和配置中的每个更改(例如,捆绑软件导入/导出,DS更改)运行Maven构建。但是一旦完成,就可以从Eclipse运行/调试测试。

我把这个项目放到了这里

HTH =)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/569616.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号