@PrePersist private void updateRedundantConfig() { // Checks to see if other SCs exist in the same partition and uses the same backend config if it // exists. if (this.blockStorageManager == null && this.getPartition() != null) { for (ServiceConfiguration s : ServiceConfigurations.listPartition(Storage.class, this.getPartition())) { StorageControllerConfiguration otherSc = (StorageControllerConfiguration) s; this.blockStorageManager = otherSc.getBlockStorageManager() != null ? otherSc.getBlockStorageManager() : null; } } }
@Override public void fireChange(ConfigurableProperty t, String newValue) throws ConfigurablePropertyException { String existingValue = (String) t.getValue(); if (existingValue != null && !"<unset>".equals(existingValue)) { throw new ConfigurablePropertyException( "Cannot change extant storage backend configuration. You must deregister all SCs in the partition before you can change the configuration value"); } else { // Try to figure out the partition name for the request String probablePartitionName = ((MultiDatabasePropertyEntry) t).getEntrySetName(); if (probablePartitionName == null) { throw new ConfigurablePropertyException( "Could not determing partition name from property to check validity"); } String[] parts = probablePartitionName.split("\\."); if (parts == null || parts.length == 0) { throw new ConfigurablePropertyException( "Could not determing partition name from property to check validity: " + probablePartitionName); } probablePartitionName = parts[0]; /*Look through the service configurations for each SC in the partition and see if the value is valid. * This step must work if we don't allow the user to change it once set. * The difficulty here is if 2 SCs are in an HA pair but have different backends installed (i.e. packages) * The implemented semantic is that if the proposed value is valid in either SC, then allow the change. */ List<ServiceConfiguration> scConfigs = null; try { scConfigs = ServiceConfigurations.listPartition(Storage.class, probablePartitionName); } catch (NoSuchElementException e) { throw new ConfigurablePropertyException( "No Storage Controller configurations found for partition: " + probablePartitionName); } final String proposedValue = newValue; final Set<String> validEntries = Sets.newHashSet(); EntityTransaction tx = Entities.get(StorageControllerConfiguration.class); try { if (!Iterables.any( scConfigs, new Predicate<ServiceConfiguration>() { @Override public boolean apply(ServiceConfiguration config) { if (config.isVmLocal()) { // Service is local, so add entries to the valid list (in case of HA configs) // and then check the local memory state validEntries.addAll(StorageManagers.list()); return StorageManagers.contains(proposedValue); } else { try { // Remote SC, so check the db for the list of valid entries. StorageControllerConfiguration scConfig = Entities.uniqueResult((StorageControllerConfiguration) config); for (String entry : Splitter.on(",").split(scConfig.getAvailableBackends())) { validEntries.add(entry); } return validEntries.contains(proposedValue); } catch (Exception e) { return false; } } } })) { // Nothing matched. throw new ConfigurablePropertyException( "Cannot modify " + t.getQualifiedName() + "." + t.getFieldName() + " new value is not a valid value. " + "Legal values are: " + Joiner.on(",").join(validEntries)); } } finally { tx.rollback(); } } }