2016-05-08 27 views
1

Ich versuche, eine Multi-Tenant-Web-Anwendung zu erstellen, und fand ein gutes Tutorial here. Dies erklärt, wie MVC konfiguriert wird, um den neuen Mandanten zu finden (mit CurrentTenantIdentifierResolver und einem MultiTenancyInterceptor, der HandlerInterceptorAdapter erweitert), drei verschiedene Datenquellen für drei verschiedene Mandanten zu konfigurieren und dem Server zur Laufzeit die richtige Datenquelle zu geben, indem er erweitertSpring Boot Jpa Multitenancy mit dynamischen Datenquellen

Nun, dies war ein guter Ausgangspunkt, um mir zu verstehen, wie Multi-Tenancy im Frühjahr und Winterschlaf arbeiten, aber ich möchte das weiter vorantreiben und ich möchte es so machen, dass die Mieter komplett dynamisch sind, dh Ich mache keine Annahmen darüber, wie viele Mieter es für eine Bewerbung geben kann.

Das ist, was ich dachte:

  • Die Anwendung konfiguriert ist, einen Pfad (nicht im Classpath, zB/usr/data/config) beim Booten zu scannen und findet verschiedene application.properties Dateien unter verschiedenen Verzeichnisse (ein Verzeichnis für jeden Mandanten) z tenantA, tenantB, tenterC ...
  • Für jede application.properties Spring boot erstellt eine Datenquelle basierend auf dieser Datei (diese Datei hat nur die Boot-Eigenschaft spring.datasource.url). Beachten Sie, dass es großartig wäre, die Spring-Boot-Eigenschaft zu verwenden, da sie mir alle Informationen liefert, die ich von der einzelnen URL benötige, wie die JDBC-Klasse und so weiter.
  • I wird jede dieser Datenquellen in einem HashMap registrieren Danach

(wie in der vorhergehenden Verbindung dargestellt), wird die Grund Multitenancy Struktur bereits in der Verbindung beschrieben zuvor erwähnten: jedes Mal wenn ein Endbenutzer auf eine Anforderung macht Im Browser erstellt der Server den Mandanten und gibt die richtige Datenquelle zurück, um die Datenbank zu finden, die verwendet werden soll.

Jeder kann mich auf einige Ressourcen hinweisen, wenn dies zuvor gemacht wurde (ich habe viel gegooglet, aber nichts bringt mich dazu), oder geben Sie einen Ratschlag, welche Federklassen/Konfigurationen verwendet werden sollen?

Vielen Dank im Voraus

Antwort

1

Das ist, was ich tun endete, wenn jemand jemals dieses Bedürfnis hat. Jede weitere Erweiterung oder Anmerkungen zu Verstößen gegen Best Practices sind sehr willkommen.

Die DataSourceProvider die AbstractDataSourceBasedMultiTenantConnectionProviderImpl erstreckt hat zwei Methoden

  • selectAnyDataSource die wieder ein @Autowired DataSource kehrt außer Kraft zu setzen, die von Feder mit der üblichen Methode der Instanziierung eine Datenquelle für eine Anwendung instanziiert wird.
  • selectDataSource(String tenant) macht folgendes:
    • bekommt den Pfad der Konfigurationsordner des Mieters
    • instanziert ein DataSourceProperties mit Eigenschaften aus der Anwendung genommen.Eigenschaftendatei, die im Konfigurationsordner des Mandanten gefunden wird
    • Erstellt und gibt eine neue DataSource über eine DataSourceBuilder zurück, wobei die Felder in den zuvor instanziierten DataSourceProperties als Eigenschaften verwendet werden (nützlich, da Spring den Treiberklassennamen dynamisch aus der Datenbank-URL gibt)

-Code hier vorgesehen ist, fühlen sie sich frei, es zu benutzen:

String configPath = [...]; // Instantiate your configuration path 
File file = new File(realPath); 
DataSourceProperties dsProp = new DataSourceProperties(); 
Properties properties = new Properties(); 
try { 
    properties.load(new FileInputStream(file)); 
} catch (IOException e) { 
    throw new TenantNotConfiguredException(tenant); // Custom exception 
} 

PropertiesConfigurationFactory<DataSourceProperties> pcf = new PropertiesConfigurationFactory<>(dsProp); 
pcf.setTargetName(DataSourceProperties.PREFIX); 
pcf.setProperties(properties); 

try { 
    dsProp = pcf.getObject(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

return DataSourceBuilder.create() 
      .url(dsProp.getUrl()) 
      .driverClassName(dsProp.getDriverClassName()) 
      .username(dsProp.getUsername()) 
      .password(dsProp.getPassword()) 
      .build(); 
Verwandte Themen