openstack4j 源码分析 (一) 入口

openstack4j 源码分析之入口

背景

去年有个整合多个openstack平台的项目,底层是华为、华3等不一样平台的openstack环境,应用管理层为java。虽然各平台功能与原生openstack有所增长,但整体接口风格仍是openstack的逻辑。因为openstack接口众多,一个个去适配接口的工做量巨大,因此决定基于openstack的java sdk来开发。对比了几种常见sdk,最后决定选用openstack4j来开发。java

  • Apache jclouds apache的开源sdk,大而全、杂,能够对接全部常见的云平台,文档较少,使用maven引入。git

  • openstack-java-sdk 由爱好者开发及维护的sdk,更新很慢,github的demo已经不能成功链接最新的openstack版本。github

  • openstack4j 官网资料、文档丰富,接口上手简单,更新快。apache

入口

openstack4j的官网demo给出的入口是api

OSClient.OSClientV3 os = OSFactory.builderV3()
                  .endpoint("http://127.0.0.1:5000/v3")
                  .credentials("admin", "secret", Identifier.byName("Default"))
                  .scopeToProject(Identifier.byName("admin"))
                  .authenticate();

OSFactory是一个抽象类,经过它咱们能够建立出不一样的OSClient,而OSClient则是咱们用来操做openstack的接口类。OSClient分为V2和V3版本,对应openstack V2 与 V3版本的认证模块(Keystone)。dom

OSClientV2 与 OSClientV3均为OSClient接口类的内部类,经过下面的代码能够看到,除了在认证模块有所区别外,其余模块没有任何区别。maven

interface OSClientV2 extends OSClient<OSClient.OSClientV2> {

        Access getAccess();

        org.openstack4j.api.identity.v2.IdentityService identity();

    }
interface OSClientV3 extends OSClient<OSClient.OSClientV3> {

        Token getToken();

        org.openstack4j.api.identity.v3.IdentityService identity();

    }

OSFactory工厂类是使用建造者模式(Builder Pattern)来将复杂的对象构造过程和主类分离的,具体的对象构造行为是由OSClientBuilder来完成,其中包含了endpoint、credentials、scopeToProject等方法来接收外界传入的登陆所需信息。ide

public abstract class OSClientBuilder<R, T extends IOSClientBuilder<R, T>> implements IOSClientBuilder<R, T> {

    String endpoint;
    String user;
    String password;

    public T endpoint(String endpoint) {
        this.endpoint = endpoint;
        return (T) this;
    }

    public T credentials(String user, String password) {
        this.user = user;
        this.password = password;
        return (T) this;
    }

登陆信息保存在OSClientBuilder对象中,而后经过authenticate()方法,根据不一样的版本进行认证。源码分析

public static class ClientV2 extends OSClientBuilder<OSClientV2, IOSClientBuilder.V2> implements IOSClientBuilder.V2 {

        @Override
        public OSClientV2 authenticate() throws AuthenticationException {
            if (tokenId != null) {
                checkArgument(tenantName != null || tenantId != null,
                        "TenantId or TenantName is required when using Token Auth");
                return (OSClientV2) OSAuthenticator.invoke(new TokenAuth(tokenId, tenantName, tenantId), endpoint, perspective,
                        config, provider);
            }

            if (raxApiKey) {
                return (OSClientV2) OSAuthenticator.invoke( new RaxApiKeyCredentials(user, password), endpoint, perspective, config, provider);
            }

            return (OSClientV2) OSAuthenticator.invoke( new Credentials(user, password, tenantName, tenantId), endpoint, perspective, config, provider);
        }

    }
public static class ClientV3 extends OSClientBuilder<OSClientV3, IOSClientBuilder.V3> implements IOSClientBuilder.V3 {

      @Override
      public OSClientV3 authenticate() throws AuthenticationException {
          if (tokenId != null && tokenId.length() > 0)
              return (OSClientV3) OSAuthenticator.invoke(new KeystoneAuth(tokenId, scope), endpoint, perspective, config,
                      provider);
          return (OSClientV3) OSAuthenticator.invoke(new KeystoneAuth(user, password, domain, scope), endpoint, perspective,
                  config, provider);
      }

}

入口处的代码主要关联三个类(接口),OSFactory、OSClientBuilder(IOSClientBuilder)、OSClient,由OSFactory调用OSClientBuilder类构建OSClient对象,而后进行认证,完成了入口处的代码逻辑。ui

能够看到,为了不因为openstack的认证方式更改而带来的openstack4j认证对象的剧烈改动,入口类之间的耦合很低,易于扩展。使用建造者模式(Builder Pattern)生成认证信息,将复杂的构建与其表示相分离,使得一样的构建能够建立不一样的表示。对于不一样的认证方式,只须要增长或者减小部分组合方法便可。

而对于大版本之间的不一样,如V2和V3,则使用工厂模式(Factory Pattern),IOSClientBuilder定义一个建立对象的接口,让其子类本身决定实例化哪个工厂类,工厂模式使其建立过程延迟到子类进行。当出现认证版本之间的差别时,只须要在IOSClientBuilder接口类中建立本身的静态工厂接口类,就能够轻松完成认证过程的更改。咱们对接华为、华3等平台时,对于不一样的认证方式,就是使用这种方式,大大减小了开发量。

类图

相关文章
相关标签/搜索