001package com.kabira.platform.switchconfig; 002 003/* 004 * $RCSfile: ConfigurationListener.java,v $ 005 * $Revision: 1.1.2.14.4.2 $ $Date: 2015/05/10 16:08:12 $ 006 * 007 * Copyright 2010-2015 TIBCO Software Inc. ALL RIGHTS RESERVED. 008 * TIBCO Software Inc. Confidential Information 009 */ 010import com.kabira.platform.DeleteTrigger; 011import com.kabira.platform.InOutParameter; 012import com.kabira.platform.KeyFieldValueList; 013import com.kabira.platform.KeyManager; 014import com.kabira.platform.KeyQuery; 015import com.kabira.platform.LockMode; 016import com.kabira.platform.ManagedObject; 017import com.kabira.platform.annotation.Managed; 018import java.util.List; 019 020/** 021 * Listener for lifecycle changes to configuration versions. 022 * <p> 023 * Instances of this class will listen for configuration 024 * lifecycle events - <code>load</code>, <code>activate</code>, 025 * <code>deactivate</code>, <code>replace</code>, and <code>remove</code>. 026 * <p> 027 * Creating a listener instance implicitly registers the instance for 028 * a configuration type. A listener instance can only listen for one 029 * configuration type. Each type 030 * may have zero, one, or more listener instances registered. If multiple 031 * listeners are registered for the same configuration type, each listener 032 * will be called for each lifecycle event. The order in which they are invoked 033 * is non-deterministic. 034 * See the 035 * Configuration chapter of the Developer's Guide for more information 036 * on configuration types. 037 * <p> 038 * This class provides both audit and lifecycle callbacks. 039 * <p> 040 * Audit methods are invoked before the state transition, and may veto 041 * the requested change if a state or consistency problem is detected. 042 * As an example, you may disallow deactivate and replace of a version 043 * if it is currently managing a connected network resource. 044 * <p> 045 * Lifecycle callbacks occur after the state transition 046 * is confirmed. In the lifecycle callbacks, you should implement any 047 * application-visible changes to follow the new configuration state - for 048 * example, creating and starting network resources based on a Config instance. 049 */ 050@Managed 051public class ConfigurationListener implements DeleteTrigger 052{ 053 private Notifier m_delegate; 054 055 /** 056 * Create an instance to listen for configuration lifecycle events. 057 * <p> 058 * All configuration listeners must provide a constructor that overrides 059 * this constructor. The configuration type must be specified in the 060 * child constructor and passed to this constructor using super. 061 * <p> 062 * Creating an instance of a configuration listener implicitly 063 * registers a listener for the configurationType. 064 * <p> 065 * @param configurationType Configuration type 066 */ 067 public ConfigurationListener(String configurationType) 068 { 069 KeyQuery<GroupKind> kq; 070 KeyFieldValueList kfvl; 071 GroupKind type; 072 073 // The configuration type is selected using the ByGroupKind key. 074 // Take a write-lock because we are going to modify the type 075 // when we install the notifier 076 // 077 kq = new KeyManager<GroupKind>().createKeyQuery( 078 GroupKind.class, "ByGroupKind"); 079 kfvl = new KeyFieldValueList(); 080 kfvl.add("groupKind", configurationType); 081 kq.defineQuery(kfvl); 082 type = kq.getOrCreateSingleResult(LockMode.WRITELOCK, null); 083 084 // Create a configuration notifier that will map the switchconfig 085 // notifier calls to the ConfigurationListener interface. 086 // 087 m_delegate = new ListenerDelegate(this); 088 089 // Register the configuration notifier. 090 // 091 InOutParameter<Notifier> notifier = new InOutParameter<Notifier>(); 092 notifier.setValue(m_delegate); 093 type.registerNotifier(notifier); 094 } 095 096 @Override 097 public void uponDelete() 098 { 099 if (m_delegate != null) 100 { 101 ManagedObject.delete(m_delegate); 102 } 103 } 104 105 /** 106 * Called when a new version has been loaded for a registered configuration 107 * type. The listener may provide additional Config instances to be appended 108 * to the version by passing them back in the <code>additions</code> 109 * parameter. 110 * <p> 111 * This method may also veto the load by throwing 112 * <code>ConfigurationException</code>. 113 * 114 * @param version Version instance that has been loaded. 115 * @param additions a list of Config instances to be added to the 116 * newly-loaded version. This will be a valid List instance supporting 117 * <code>add</code> when the method is invoked. 118 * @throws ConfigurationException thrown by the implementation 119 * in order to veto the version load. 120 */ 121 public void loaded( 122 final Version version, 123 List<Config> additions) 124 throws ConfigurationException 125 { 126 /* TBI by subtype */ 127 } 128 129 /** 130 * Called when a configuration version has been activated for a registered 131 * configuration type. Note that this is called only when there is no 132 * version already active for the configuration that <code>version</code> 133 * belongs to. If the new version is replacing a previous active version, 134 * then {@link #replaced} is called instead. 135 * <p> 136 * Implementations that modify non-transactional resources should 137 * manage this carefully in activated() and deactivated(). See the 138 * Transactions chapter of the Developer's Guide. 139 * 140 * @param version A version instance that has been activated. 141 */ 142 public void activated(final Version version) 143 { 144 /* TBI by subtype */ 145 } 146 147 /** 148 * Called when a configuration version has been deactivated for a registered 149 * configuration type. Note that this is called only when there is no 150 * other version that will immediately replace this one. If a new version 151 * is replacing this version, then 152 * {@link #replaced} is called instead. 153 * @param version A version instance that has been deactivated. 154 */ 155 public void deactivated(final Version version) 156 { 157 /* TBI by subtype */ 158 } 159 160 /** 161 * Called when a configuration version has been activated, replacing an 162 * existing, active, version. 163 * <p> 164 * The default implementation of this method is to call the 165 * <code>deactivated</code> and <code>activated</code> 166 * methods directly. 167 * <p> 168 * @param deactivated Version instance that has been deactivated. 169 * @param activated Version instance that has been activated. 170 */ 171 public void replaced(final Version deactivated, 172 final Version activated) 173 { 174 deactivated(deactivated); 175 activated(activated); 176 } 177 178 /** 179 * Called when a configuration version has been removed. 180 * @param version Version instance that has been removed. 181 */ 182 public void removed(final Version version) 183 { 184 /* TBI by subtype */ 185 } 186 187 /** 188 * Called when a configuration version is loaded for a registered 189 * configuration type. This operation will be called after 190 * the entire version has been loaded. This means that 191 * <code>versionLoaded</code> will be invoked on all registered listeners 192 * before <code>auditLoad</code> is called on any listener. 193 * <p> 194 * This method should check whether the given version is 195 * legal to be loaded. If this version is not legal, the listener 196 * may veto the version by throwing <code>ConfigurationException</code>. 197 * 198 * @param version The version instance about to be loaded. 199 * @throws ConfigurationException to veto the entire version load. 200 */ 201 public void auditLoad(final Version version) 202 throws ConfigurationException 203 { 204 /* TBI by subtype */ 205 } 206 207 /** 208 * Called before a configuration version is activated for a registered 209 * configuration type. Note that this is called only when there is no 210 * version already active for the configuration that <code>version</code> 211 * belongs to. If the new version will replace a previous active version, 212 * then {@link #auditReplace} is called instead. 213 * <p> 214 * This method should check whether the given version is 215 * legal to be activated. It may veto the activation by throwing 216 * <code>ConfigurationException</code>. 217 * <p> 218 * @param version The version instance to be activated. 219 * @throws ConfigurationException to veto the version activation. 220 */ 221 public void auditActivate(final Version version) 222 throws ConfigurationException 223 { 224 /* TBI by subtype */ 225 } 226 /** 227 * Called before a configuration version is deactivated for a registered 228 * configuration type. Note that this is called only when there is no 229 * version being activated for the configuration that <code>version</code> 230 * belongs to. If a new version will replace the previously-active version, 231 * then {@link #auditReplace} is called instead. 232 * <p> 233 * This method should check whether the given version is 234 * legal to be deactivated. It may veto the deactivation by throwing 235 * <code>ConfigurationException</code>. 236 * <p> 237 * @param version The version instance to be deactivated. 238 * @throws ConfigurationException to veto the version deactivation. 239 */ 240 public void auditDeactivate( 241 final Version version) throws ConfigurationException 242 { 243 /* TBI by subtype */ 244 } 245 246 /** 247 * Called before a configuration version is replacing the active version 248 * for a registered configuration type. 249 * Note that this is called only when a new version is replacing an 250 * existing active version. 251 * <p> 252 * This method should check whether the given version replacement is 253 * legal. It may veto the replace operation by throwing 254 * <code>ConfigurationException</code>. 255 * <p> 256 * @param deactivating The version to be deactivated. 257 * @param activating The version to be activated. 258 * @throws ConfigurationException to veto the version replace. 259 */ 260 public void auditReplace( 261 final Version deactivating, 262 final Version activating) 263 throws ConfigurationException 264 { 265 /* TBI by subtype */ 266 } 267 268 /** 269 * Called before a configuration version is removed 270 * for a registered configuration type. 271 * <p> 272 * This method should check whether the given remove is 273 * legal. It may veto the remove operation by throwing 274 * <code>ConfigurationException</code>. 275 * <p> 276 * @param version The version to be removed. 277 * @throws ConfigurationException to veto the version removal. 278 */ 279 public void auditRemove(final Version version) throws ConfigurationException 280 { 281 /* TBI by subtype */ 282 } 283}