/** * Looks up the registered factories and creates a CompositeDataSource * using them. * * @return a new DataSource */ public static CompositeDataSource createDataSource() { CompositeDataSource composite = new CompositeDataSource(); composite.setConfiguration(readConfiguration(composite, "datasources")); ServiceLoaderOSGiWrapper.load(DataSourceProvider.class, log, composite::putDataSource); return composite; }
/** * Adds/replaces the data source corresponding to the given name. * * @param name the name of the data source * @param dataSource the data source to add/replace */ public void putDataSource(final String name, final DataSource dataSource) { putDataSource(new DataSourceProvider() { @Override public String getName() { return name; } @Override public DataSource createInstance() { return dataSource; } }); }
@Override public void connectWrite(WriteRecipe writeRecipe) { Map<String, WriteRecipe> splitRecipes = splitRecipe(writeRecipe); for (Entry<String, WriteRecipe> entry : splitRecipes.entrySet()) { String dataSource = entry.getKey(); WriteRecipe splitWriteRecipe = entry.getValue(); retrieveDataSource(dataSource).connectWrite(splitWriteRecipe); } }
public void programmaticCompositeDataSourceConfiguration() { // The recommended method to configure data sources is through // the configuration files in DIIRT_HOME. // If is needed, you can still change the configuration through // the programmatic API. This can be useful for unit testing // or standalone applications. You should not do this in shared // environment, like CS-Studio. // Create a composite data source, and add different data sources. // You can either add a DataSourceProvider or a DataSource. CompositeDataSource composite = new CompositeDataSource(); composite.putDataSource(new JCADataSourceProvider()); composite.putDataSource("sim", new SimulationDataSource()); // If no prefix is given to a channel, use JCA as default composite.setConfiguration(new CompositeDataSourceConfiguration().defaultDataSource("ca")); // Set the composite as the default PVManager.setDefaultDataSource(composite); // For more options, check CompositeDataSource. }
@Override public void disconnectWrite(WriteRecipe writeRecipe) { Map<String, WriteRecipe> splitRecipe = splitRecipe(writeRecipe); for (Map.Entry<String, WriteRecipe> en : splitRecipe.entrySet()) { String dataSource = en.getKey(); WriteRecipe splitWriteRecipe = en.getValue(); dataSources.get(dataSource).disconnectWrite(splitWriteRecipe); } }
@Override public void connectRead(ReadRecipe readRecipe) { Map<String, ReadRecipe> splitRecipe = splitRecipe(readRecipe); // Dispatch calls to all the data sources for (Map.Entry<String, ReadRecipe> entry : splitRecipe.entrySet()) { try { retrieveDataSource(entry.getKey()).connectRead(entry.getValue()); } catch (RuntimeException ex) { // If data source fail, still go and connect the others readRecipe.getChannelReadRecipes().iterator().next().getReadSubscription().getExceptionWriteFunction().writeValue(ex); } } }
@Override public void disconnectRead(ReadRecipe readRecipe) { Map<String, ReadRecipe> splitRecipe = splitRecipe(readRecipe); // Dispatch calls to all the data sources for (Map.Entry<String, ReadRecipe> entry : splitRecipe.entrySet()) { try { dataSources.get(entry.getKey()).disconnectRead(entry.getValue()); } catch(RuntimeException ex) { // If a data source fails, still go and disconnect the others readRecipe.getChannelReadRecipes().iterator().next().getReadSubscription().getExceptionWriteFunction().writeValue(ex); } } }
private Map<String, ReadRecipe> splitRecipe(ReadRecipe readRecipe) { Map<String, ReadRecipe> splitRecipe = new HashMap<String, ReadRecipe>(); // Iterate through the recipe to understand how to distribute // the calls Map<String, Collection<ChannelReadRecipe>> routingRecipes = new HashMap<String, Collection<ChannelReadRecipe>>(); for (ChannelReadRecipe channelRecipe : readRecipe.getChannelReadRecipes()) { String name = nameOf(channelRecipe.getChannelName()); String dataSource = sourceOf(channelRecipe.getChannelName()); if (dataSource == null) throw new IllegalArgumentException("Channel " + name + " uses the default data source but one was never set."); // Add recipe for the target dataSource if (routingRecipes.get(dataSource) == null) { routingRecipes.put(dataSource, new HashSet<ChannelReadRecipe>()); } routingRecipes.get(dataSource).add(new ChannelReadRecipe(name, channelRecipe.getReadSubscription())); } // Create the recipes for (Entry<String, Collection<ChannelReadRecipe>> entry : routingRecipes.entrySet()) { splitRecipe.put(entry.getKey(), new ReadRecipe(entry.getValue())); } return splitRecipe; }
private Map<String, WriteRecipe> splitRecipe(WriteRecipe writeRecipe) { // Chop the recipe along different data sources Map<String, Collection<ChannelWriteRecipe>> recipes = new HashMap<String, Collection<ChannelWriteRecipe>>(); for (ChannelWriteRecipe channelWriteRecipe : writeRecipe.getChannelWriteRecipes()) { String channelName = nameOf(channelWriteRecipe.getChannelName()); String dataSource = sourceOf(channelWriteRecipe.getChannelName()); Collection<ChannelWriteRecipe> channelWriteRecipes = recipes.get(dataSource); if (channelWriteRecipes == null) { channelWriteRecipes = new ArrayList<ChannelWriteRecipe>(); recipes.put(dataSource, channelWriteRecipes); } channelWriteRecipes.add(new ChannelWriteRecipe(channelName, channelWriteRecipe.getWriteSubscription())); } Map<String, WriteRecipe> splitRecipes = new HashMap<String, WriteRecipe>(); for (Map.Entry<String, Collection<ChannelWriteRecipe>> en : recipes.entrySet()) { String dataSource = en.getKey(); Collection<ChannelWriteRecipe> val = en.getValue(); WriteRecipe newWriteRecipe = new WriteRecipe(val); splitRecipes.put(dataSource, newWriteRecipe); } return splitRecipes; }