使用 jclouds 和 Openstack Swift 进行单元测试的瞬态模式不起作用

Transient mode for unit tests with jclouds and Openstack Swift doesn't work

我刚刚迁移到 jclouds 2.0.0(它被认为是一些不可重复操作的问题,它做到了)。这是依赖项

    <dependency>
        <groupId>org.apache.jclouds.driver</groupId>
        <artifactId>jclouds-slf4j</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.jclouds.api</groupId>
        <artifactId>openstack-keystone</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.jclouds.api</groupId>
        <artifactId>openstack-swift</artifactId>
        <version>2.0.0</version>
    </dependency>

我想对我的代码进行单元测试。但是当我使用 transient 作为提供者时:

SwiftApi swiftApi = ContextBuilder.newBuilder("transient")
                .endpoint(endpoint)
                .credentials(user, password)
                .modules(modules)
                .overrides(overrides)
                .buildApi(SwiftApi.class);

我得到这个异常:

com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for org.jclouds.openstack.swift.v1.SwiftApi was bound.
  while locating org.jclouds.openstack.swift.v1.SwiftApi

1 error

    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1009)
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:651)
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:643)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProvider.openConnections(SimpleSwiftConnectionProvider.java:91)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProvider.<init>(SimpleSwiftConnectionProvider.java:67)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProviderTest.getContainer(SimpleSwiftConnectionProviderTest.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

使用 openstack-swift 作为提供者(以及正确的凭据和端点)的相同代码 运行 工作正常。 将任何其他字符串作为 newBuilder 函数参数传递原因:

java.util.NoSuchElementException: key [wrongstring] not in the list of providers or apis: {apis=[openstack-keystone, openstack-swift, transient]}
    at org.jclouds.ContextBuilder.newBuilder(ContextBuilder.java:175)

这让我觉得 transient 应该得到支持。但是如何让它发挥作用呢?

您无法创建临时 blobstore 的 SwiftApi 视图;相反,您必须使用便携式 BlobStore 视图:

String provider = ...;  // openstack-swift or transient
BlobStoreContext context = ContextBuilder.newBuilder(provider)
            .endpoint(endpoint)
            .credentials(user, password)
            .buildApi(BlobStoreContext.class);
BlobStore blobStore = context.getBlobStore();
// interact with blobStore, e.g., get, put
...
context.close();