My Application design contains fixed and dynamically DataMaps to connect to different (Oracle) DB instances/users. For simplicity i did split them into two different Cayenne Projects.
For every customer, load the dynamic DataMap with a second ServerRuntimeBuilder with the necessary modifications (change name and defaultschema):
...
List<Customer> allCustomers = Customer.allCustomers(this.cayenneRuntime1.newContext());
for (Customer customer : allCustomers) {
final String dbPrefix = customer.getDbprefix();
ServerRuntimeBuilder builder = ServerRuntime.builder();
// load and modify DataMap
builder.addConfig("ApacheCayenne/Data/cayenne-dynamicDomain.xml");
builder.addModule(binder -> {
binder.bind(DataMapLoader.class).to(MyDataMapLoader.class);
ServerModule.contributeProperties(binder).put("CUSTOMER_PREFIX", dbPrefix);
});
ServerRuntime cayenneRuntime2 = builder.build();
LOG.info("Initialized customer model " + customer + " prefix: " + customer.getDbprefix());
// TODO Merge with cayenneRuntime1?
}
public class MyDataMapLoader extends XMLDataMapLoader {
@Inject
private RuntimeProperties properties;
@Override
public DataMap load(Resource configurationResource) throws CayenneRuntimeException {
DataMap map = super.load(configurationResource);
// Dynamically set name and default schema to map
String dbPrefix = properties.get("CUSTOMER_PREFIX");
map.setName(customer1.dbPrefix + "...")
map.setDefaultSchema(customer1.dbPrefix + "...")
return map;
}
}
And additionally an own ConfiguredDataSource implementation, that takes care about the JDBC connection URL and credentials. That part works fine so far.
My Problem: with this design i end up having 1 + n ServerRuntimes for every customer. But in the end i would want to have a singe ServerRuntime.
a) Is it possible merge these ServerRuntimes on the fly with Cayenne 4.0RC1 functions and future releases?
b) Do i need to read the dynamic maps with the help of cayenne-project library as described here. Modify and store every dynamic Project to the filesystem. After processing all my customers, create a final ServerRuntime with all the Cayenne Projects using the described way with an ExecutingMergerContext or with this Merging Multiple Projects?
ServerRuntime runtime = ServerRuntime.builder()
.addConfig("com/example/cayenne-fixed-project.xml")
.addConfig("org/foo/cayenne-dynamic-Customer1.xml")
.addConfig("org/foo/cayenne-dynamic-Customer2.xml")
.build();
Thanks in advance for helping me out.
I'd start runtime1 to get the config data, and then create runtime2 that contains both fixed and dynamic maps, and also a custom DataMap loader to dynamically rewrite name and schema:
ServerRuntime runtime2 = ServerRuntime.builder()
.addConfig("com/example/cayenne-fixed-project.xml")
.addConfig("org/foo/cayenne-dynamic-Customer1.xml")
.addConfig("org/foo/cayenne-dynamic-Customer2.xml")
.addModule(..)
.build();
Just don't forget to shut down runtime1 when you are done with it, so you'll only have a single runtime at the end.