1 17 package org.apache.geronimo.kernel.config; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.io.PrintWriter ; 23 import java.io.File ; 24 import java.net.URL ; 25 import java.util.Collection ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.Set ; 29 import java.util.List ; 30 import java.util.Collections ; 31 import java.util.ArrayList ; 32 import java.util.Properties ; 33 import java.util.Map ; 34 import java.util.LinkedHashSet ; 35 36 import org.apache.geronimo.gbean.AbstractName; 37 import org.apache.geronimo.gbean.AbstractNameQuery; 38 import org.apache.geronimo.gbean.GAttributeInfo; 39 import org.apache.geronimo.gbean.GBeanData; 40 import org.apache.geronimo.gbean.GReferenceInfo; 41 import org.apache.geronimo.gbean.InvalidConfigurationException; 42 import org.apache.geronimo.gbean.ReferencePatterns; 43 import org.apache.geronimo.kernel.GBeanAlreadyExistsException; 44 import org.apache.geronimo.kernel.GBeanNotFoundException; 45 import org.apache.geronimo.kernel.Kernel; 46 import org.apache.geronimo.kernel.ClassLoading; 47 import org.apache.geronimo.kernel.InternalKernelException; 48 import org.apache.geronimo.kernel.basic.BasicKernel; 49 import org.apache.geronimo.kernel.management.State; 50 import org.apache.geronimo.kernel.repository.Artifact; 51 import org.apache.commons.logging.Log; 52 import org.apache.commons.logging.LogFactory; 53 54 57 public final class ConfigurationUtil { 58 private static final Log log = LogFactory.getLog(ConfigurationUtil.class); 59 private static final ConfigurationMarshaler configurationMarshaler; 60 61 static { 62 ConfigurationMarshaler marshaler = null; 63 String marshalerClass = System.getProperty("Xorg.apache.geronimo.kernel.config.Marshaler"); 64 if (marshalerClass != null) { 65 try { 66 marshaler = createConfigurationMarshaler(marshalerClass); 67 } catch (Exception e) { 68 log.error("Error creating configuration marshaler class " + marshalerClass , e); 69 } 70 } 71 72 80 if (marshaler == null) { 81 marshaler = new SerializedConfigurationMarshaler(); 82 } 83 84 configurationMarshaler = marshaler; 85 } 86 87 public static ConfigurationMarshaler createConfigurationMarshaler(String marshalerClass) throws Exception { 88 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 89 Class clazz = null; 90 if (classLoader != null) { 91 try { 92 clazz = ClassLoading.loadClass(marshalerClass, classLoader); 93 } catch (ClassNotFoundException ignored) { 94 } 96 } 97 if (clazz == null) { 98 classLoader = ConfigurationUtil.class.getClassLoader(); 99 try { 100 clazz = ClassLoading.loadClass(marshalerClass, classLoader); 101 } catch (ClassNotFoundException ignored) { 102 } 104 } 105 106 if (clazz != null) { 107 Object object = clazz.newInstance(); 108 if (object instanceof ConfigurationMarshaler) { 109 return (ConfigurationMarshaler) object; 110 } else { 111 log.warn("Configuration marshaler class is not an instance of ConfigurationMarshaler " + marshalerClass + ": using default configuration "); 112 } 113 } 114 return null; 115 } 116 117 private ConfigurationUtil() { 118 } 119 120 public static GBeanState newGBeanState(Collection gbeans) { 121 return configurationMarshaler.newGBeanState(gbeans); 122 } 123 124 public static AbstractName loadBootstrapConfiguration(Kernel kernel, InputStream in, ClassLoader classLoader) throws Exception { 125 ConfigurationData configurationData = readConfigurationData(in); 126 return loadBootstrapConfiguration(kernel, configurationData, classLoader); 127 } 128 129 public static AbstractName loadBootstrapConfiguration(Kernel kernel, ConfigurationData configurationData, ClassLoader classLoader) throws Exception { 130 if (kernel == null) throw new NullPointerException ("kernel is null"); 131 if (configurationData == null) throw new NullPointerException ("configurationData is null"); 132 if (classLoader == null) throw new NullPointerException ("classLoader is null"); 133 134 List dependencies = configurationData.getEnvironment().getDependencies(); 136 if (!dependencies.isEmpty()) { 137 configurationData.getEnvironment().setDependencies(Collections.EMPTY_SET); 138 } 140 141 Artifact configId = configurationData.getId(); 143 AbstractName abstractName = Configuration.getConfigurationAbstractName(configId); 144 GBeanData gbeanData = new GBeanData(abstractName, Configuration.GBEAN_INFO); 145 gbeanData.setAttribute("configurationData", configurationData); 146 gbeanData.setAttribute("configurationResolver", new ConfigurationResolver(configurationData, null, null)); 147 148 kernel.loadGBean(gbeanData, classLoader); 150 kernel.startGBean(gbeanData.getAbstractName()); 151 152 Configuration configuration = (Configuration) kernel.getGBean(gbeanData.getAbstractName()); 153 154 startConfigurationGBeans(configuration.getAbstractName(), configuration, kernel); 156 157 ConfigurationManager configurationManager = getConfigurationManager(kernel); 158 configurationManager.loadConfiguration(configId); 159 return gbeanData.getAbstractName(); 160 } 161 162 public static void writeConfigurationData(ConfigurationData configurationData, OutputStream out) throws IOException { 163 configurationMarshaler.writeConfigurationData(configurationData, out); 164 } 165 166 public static ConfigurationData readConfigurationData(InputStream in) throws IOException , ClassNotFoundException { 167 return configurationMarshaler.readConfigurationData(in); 168 } 169 170 public static void writeConfigInfo(PrintWriter writer, ConfigurationData configurationData) { 171 writeConfigInfo("", writer, configurationData); 172 } 173 private static void writeConfigInfo(String prefix, PrintWriter writer, ConfigurationData configurationData) { 174 writer.println(prefix+"id=" + configurationData.getId()); 175 writer.println(prefix+"type=" + configurationData.getModuleType()); 176 writer.println(prefix+"created=" + configurationData.getCreated()); 177 Set ownedConfigurations = configurationData.getOwnedConfigurations(); 178 int i = 0; 179 for (Iterator iterator = ownedConfigurations.iterator(); iterator.hasNext();) { 180 Artifact ownedConfiguration = (Artifact) iterator.next(); 181 writer.println(prefix+"owned." + i++ + "=" + ownedConfiguration); 182 } 183 i = 0; 184 for (Iterator it = configurationData.getChildConfigurations().values().iterator(); it.hasNext(); i++) { 185 ConfigurationData data = (ConfigurationData) it.next(); 186 writeConfigInfo("child."+i+".", writer, data); 187 } 188 writer.flush(); 189 } 190 191 public static ConfigurationInfo readConfigurationInfo(InputStream in, AbstractName storeName, File inPlaceLocation) throws IOException { 192 Properties properties = new Properties (); 193 properties.load(in); 194 return readConfigurationInfo("", properties, storeName, inPlaceLocation); 195 } 196 private static ConfigurationInfo readConfigurationInfo(String prefix, Properties properties, AbstractName storeName, File inPlaceLocation) throws IOException { 197 String id = properties.getProperty(prefix+"id"); 198 Artifact configId = Artifact.create(id); 199 200 String type = properties.getProperty(prefix+"type"); 201 ConfigurationModuleType moduleType = ConfigurationModuleType.getByName(type); 202 if (moduleType == null) { 203 throw new IllegalArgumentException ("Unknown module type: " + type); 204 } 205 206 String created = properties.getProperty(prefix+"created"); 207 long time; 208 try { 209 time = Long.parseLong(created); 210 } catch (NumberFormatException e) { 211 throw new IllegalArgumentException ("Invalid created time: " + created); 212 } 213 214 LinkedHashSet ownedConfigurations = new LinkedHashSet (); 215 for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext();) { 216 Map.Entry entry = (Map.Entry ) iterator.next(); 217 String name = (String ) entry.getKey(); 218 if (name.startsWith(prefix+"owned.")) { 219 String value = (String ) entry.getValue(); 220 Artifact ownedConfiguration = Artifact.create(value); 221 ownedConfigurations.add(ownedConfiguration); 222 } 223 } 224 LinkedHashSet childConfigurations = new LinkedHashSet (); 225 int test = 0; 226 while(true) { 227 String next = prefix+"child."+test+"."; 228 String value = properties.getProperty(next+".id"); 229 if(value == null) { 230 break; 231 } 232 childConfigurations.add(readConfigurationInfo(next, properties, storeName, inPlaceLocation)); 233 ++test; 234 } 235 236 return new ConfigurationInfo(storeName, configId, moduleType, time, ownedConfigurations, childConfigurations, inPlaceLocation); 237 } 238 239 245 public static ConfigurationManager getConfigurationManager(Kernel kernel) { 246 Set names = kernel.listGBeans(new AbstractNameQuery(ConfigurationManager.class.getName())); 247 for (Iterator iterator = names.iterator(); iterator.hasNext();) { 248 AbstractName abstractName = (AbstractName) iterator.next(); 249 if (!kernel.isRunning(abstractName)) { 250 iterator.remove(); 251 } 252 } 253 if (names.isEmpty()) { 254 throw new IllegalStateException ("A Configuration Manager could not be found in the kernel"); 255 } 256 if (names.size() > 1) { 257 throw new IllegalStateException ("More than one Configuration Manager was found in the kernel"); 258 } 259 AbstractName configurationManagerName = (AbstractName) names.iterator().next(); 260 return (ConfigurationManager) kernel.getProxyManager().createProxy(configurationManagerName, ConfigurationManager.class); 261 } 262 263 269 public static EditableConfigurationManager getEditableConfigurationManager(Kernel kernel) { 270 Set names = kernel.listGBeans(new AbstractNameQuery(EditableConfigurationManager.class.getName())); 271 for (Iterator iterator = names.iterator(); iterator.hasNext();) { 272 AbstractName abstractName = (AbstractName) iterator.next(); 273 if (!kernel.isRunning(abstractName)) { 274 iterator.remove(); 275 } 276 } 277 if (names.isEmpty()) { 278 return null; } 280 if (names.size() > 1) { 281 throw new IllegalStateException ("More than one Configuration Manager was found in the kernel"); 282 } 283 AbstractName configurationManagerName = (AbstractName) names.iterator().next(); 284 return (EditableConfigurationManager) kernel.getProxyManager().createProxy(configurationManagerName, EditableConfigurationManager.class); 285 } 286 287 public static void releaseConfigurationManager(Kernel kernel, ConfigurationManager configurationManager) { 288 kernel.getProxyManager().destroyProxy(configurationManager); 289 } 290 291 static void preprocessGBeanData(AbstractName configurationName, Configuration configuration, GBeanData gbeanData) throws InvalidConfigException { 292 for (Iterator references = gbeanData.getReferencesNames().iterator(); references.hasNext();) { 293 String referenceName = (String ) references.next(); 294 GReferenceInfo referenceInfo = gbeanData.getGBeanInfo().getReference(referenceName); 295 if (referenceInfo == null) { 296 throw new InvalidConfigException("No reference named " + referenceName + " in gbean " + gbeanData.getAbstractName()); 297 } 298 boolean isSingleValued = !referenceInfo.getProxyType().equals(Collection .class.getName()); 299 if (isSingleValued) { 300 ReferencePatterns referencePatterns = gbeanData.getReferencePatterns(referenceName); 301 AbstractName abstractName; 302 try { 303 abstractName = configuration.findGBean(referencePatterns); 304 } catch (GBeanNotFoundException e) { 305 throw new InvalidConfigException("Unable to resolve reference \"" + referenceName + "\" in gbean " + gbeanData.getAbstractName() + " to a gbean matching the pattern " + referencePatterns, e); 306 } 307 gbeanData.setReferencePatterns(referenceName, new ReferencePatterns(abstractName)); 308 } 309 } 310 311 Set newDependencies = new HashSet (); 312 for (Iterator dependencyIterator = gbeanData.getDependencies().iterator(); dependencyIterator.hasNext();) { 313 ReferencePatterns referencePatterns = (ReferencePatterns) dependencyIterator.next(); 314 AbstractName abstractName; 315 try { 316 abstractName = configuration.findGBean(referencePatterns); 317 } catch (GBeanNotFoundException e) { 318 throw new InvalidConfigException("Unable to resolve dependency in gbean " + gbeanData.getAbstractName(), e); 319 } 320 newDependencies.add(new ReferencePatterns(abstractName)); 321 } 322 gbeanData.setDependencies(newDependencies); 323 324 GAttributeInfo attribute = gbeanData.getGBeanInfo().getAttribute("configurationBaseUrl"); 327 if (attribute != null && attribute.getType().equals("java.net.URL")) { 328 try { 329 Set set = configuration.getConfigurationResolver().resolve(""); 330 if (set.size() != 1) { 331 throw new AssertionError ("Expected one match for pattern \".\", but got " + set.size() + " matches"); 332 } 333 URL baseURL = (URL ) set.iterator().next(); 334 gbeanData.setAttribute("configurationBaseUrl", baseURL); 335 } catch (Exception e) { 336 throw new InvalidConfigException("Unable to set attribute named " + "configurationBaseUrl" + " in gbean " + gbeanData.getAbstractName(), e); 337 } 338 } 339 340 gbeanData.addDependency(configurationName); 342 } 343 344 static void startConfigurationGBeans(AbstractName configurationName, Configuration configuration, Kernel kernel) throws InvalidConfigException { 345 List gbeans = new ArrayList (configuration.getGBeans().values()); 346 Collections.sort(gbeans, new GBeanData.PriorityComparator()); 347 348 List loaded = new ArrayList (gbeans.size()); 349 List started = new ArrayList (gbeans.size()); 350 351 try { 352 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { 354 GBeanData gbeanData = (GBeanData) iterator.next(); 355 356 gbeanData = new GBeanData(gbeanData); 358 359 preprocessGBeanData(configurationName, configuration, gbeanData); 361 362 try { 363 kernel.loadGBean(gbeanData, configuration.getConfigurationClassLoader()); 364 loaded.add(gbeanData.getAbstractName()); 365 } catch (GBeanAlreadyExistsException e) { 366 throw new InvalidConfigException(e); 367 } catch (Throwable e) { 368 log.warn("Could not load gbean " + gbeanData.getAbstractName(), e); 369 throw e; 370 } 371 } 372 373 try { 374 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { 376 GBeanData gbeanData = (GBeanData) iterator.next(); 377 AbstractName gbeanName = gbeanData.getAbstractName(); 378 kernel.startRecursiveGBean(gbeanName); 379 started.add(gbeanName); 380 } 381 382 List unstarted = new ArrayList (); 384 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { 385 GBeanData gbeanData = (GBeanData) iterator.next(); 386 AbstractName gbeanName = gbeanData.getAbstractName(); 387 if (State.RUNNING_INDEX != kernel.getGBeanState(gbeanName)) { 388 String stateReason = null; 389 if (kernel instanceof BasicKernel) { 390 stateReason = ((BasicKernel) kernel).getStateReason(gbeanName); 391 } 392 String name = gbeanName.toURI().getQuery(); 393 if (stateReason != null) { 394 unstarted.add("The service " + name + " did not start because " + stateReason); 395 } else { 396 unstarted.add("The service " + name + " did not start for an unknown reason"); 397 } 398 } 399 } 400 if (!unstarted.isEmpty()) { 401 StringBuffer message = new StringBuffer (); 402 message.append("Configuration ").append(configuration.getId()).append(" failed to start due to the following reasons:\n"); 403 for (Iterator iterator = unstarted.iterator(); iterator.hasNext();) { 404 String reason = (String ) iterator.next(); 405 message.append(" ").append(reason).append("\n"); 406 } 407 throw new InvalidConfigurationException(message.toString()); 408 } 409 } catch (GBeanNotFoundException e) { 410 throw new InvalidConfigException(e); 411 } 412 413 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { 414 Configuration childConfiguration = (Configuration) iterator.next(); 415 ConfigurationUtil.startConfigurationGBeans(configurationName, childConfiguration, kernel); 416 } 417 } catch (Throwable e) { 418 for (Iterator iterator = started.iterator(); iterator.hasNext();) { 419 AbstractName gbeanName = (AbstractName) iterator.next(); 420 try { 421 kernel.stopGBean(gbeanName); 422 } catch (GBeanNotFoundException ignored) { 423 } catch (IllegalStateException ignored) { 424 } catch (InternalKernelException kernelException) { 425 log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException); 426 } 427 } 428 for (Iterator iterator = loaded.iterator(); iterator.hasNext();) { 429 AbstractName gbeanName = (AbstractName) iterator.next(); 430 try { 431 kernel.unloadGBean(gbeanName); 432 } catch (GBeanNotFoundException ignored) { 433 } catch (IllegalStateException ignored) { 434 } catch (InternalKernelException kernelException) { 435 log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException); 436 } 437 } 438 if (e instanceof Error ) { 439 throw (Error ) e; 440 } 441 if (e instanceof InvalidConfigException) { 442 throw (InvalidConfigException) e; 443 } 444 throw new InvalidConfigException("Unknown start exception", e); 445 } 446 } 447 } 448 | Popular Tags |