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等平臺時,對於不一樣的認證方式,就是使用這種方式,大大減小了開發量。

類圖

相關文章
相關標籤/搜索