001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.jetty6.cluster.wadi.builder;
017:
018: import java.net.URI;
019: import java.net.URISyntaxException;
020: import java.util.Collections;
021: import java.util.HashSet;
022: import java.util.Set;
023:
024: import javax.xml.namespace.QName;
025:
026: import org.apache.geronimo.clustering.wadi.BasicWADISessionManager;
027: import org.apache.geronimo.clustering.wadi.WADISessionManagerConfigInfo;
028: import org.apache.geronimo.common.DeploymentException;
029: import org.apache.geronimo.deployment.DeploymentContext;
030: import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
031: import org.apache.geronimo.deployment.service.EnvironmentBuilder;
032: import org.apache.geronimo.gbean.AbstractName;
033: import org.apache.geronimo.gbean.AbstractNameQuery;
034: import org.apache.geronimo.gbean.GBeanData;
035: import org.apache.geronimo.gbean.GBeanInfo;
036: import org.apache.geronimo.gbean.GBeanInfoBuilder;
037: import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
038: import org.apache.geronimo.jetty6.JettyWebAppContext;
039: import org.apache.geronimo.jetty6.cluster.ClusteredSessionHandlerFactory;
040: import org.apache.geronimo.jetty6.cluster.wadi.WADIClusteredPreHandlerFactory;
041: import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
042: import org.apache.geronimo.kernel.GBeanNotFoundException;
043: import org.apache.geronimo.kernel.config.Configuration;
044: import org.apache.geronimo.kernel.repository.Environment;
045: import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
046: import org.apache.geronimo.schema.NamespaceElementConverter;
047: import org.apache.geronimo.schema.SchemaConversionUtils;
048: import org.apache.geronimo.xbeans.geronimo.GerClusteringWadiDocument;
049: import org.apache.geronimo.xbeans.geronimo.GerClusteringWadiType;
050: import org.apache.geronimo.xbeans.geronimo.naming.GerPatternType;
051: import org.apache.xmlbeans.QNameSet;
052: import org.apache.xmlbeans.XmlObject;
053:
054: /**
055: *
056: * @version $Rev$ $Date$
057: */
058: public class WADIJettyClusteringBuilder implements
059: NamespaceDrivenBuilder {
060: private static final QName CLUSTERING_WADI_QNAME = GerClusteringWadiDocument.type
061: .getDocumentElementName();
062: private static final QNameSet CLUSTERING_WADI_QNAME_SET = QNameSet
063: .singleton(CLUSTERING_WADI_QNAME);
064:
065: static {
066: SchemaConversionUtils
067: .registerNamespaceConversions(Collections
068: .singletonMap(CLUSTERING_WADI_QNAME
069: .getLocalPart(),
070: new NamespaceElementConverter(
071: CLUSTERING_WADI_QNAME
072: .getNamespaceURI())));
073: }
074:
075: private final int defaultSweepInterval;
076: private final int defaultNumPartitions;
077: private final AbstractNameQuery defaultBackingStrategyFactoryName;
078: private final AbstractNameQuery defaultClusterName;
079: private final Environment defaultEnvironment;
080:
081: public WADIJettyClusteringBuilder(int defaultSweepInterval,
082: int defaultNumPartitions,
083: AbstractNameQuery defaultBackingStrategyFactoryName,
084: AbstractNameQuery defaultClusterName,
085: Environment defaultEnvironment) {
086: if (defaultSweepInterval < 1) {
087: throw new IllegalArgumentException(
088: "defaultSweepInterval is lower than 1");
089: } else if (defaultNumPartitions < 1) {
090: throw new IllegalArgumentException(
091: "defaultNumPartitions is lower than 1");
092: } else if (null == defaultBackingStrategyFactoryName) {
093: throw new IllegalArgumentException(
094: "defaultBackingStrategyFactoryName is required");
095: } else if (null == defaultClusterName) {
096: throw new IllegalArgumentException(
097: "defaultClusterName is required");
098: } else if (null == defaultEnvironment) {
099: throw new IllegalArgumentException(
100: "defaultEnvironment is required");
101: }
102: this .defaultSweepInterval = defaultSweepInterval;
103: this .defaultNumPartitions = defaultNumPartitions;
104: this .defaultBackingStrategyFactoryName = defaultBackingStrategyFactoryName;
105: this .defaultClusterName = defaultClusterName;
106: this .defaultEnvironment = defaultEnvironment;
107: }
108:
109: public void buildEnvironment(XmlObject container,
110: Environment environment) throws DeploymentException {
111: if (getWadiClusterConfig(container) != null) {
112: EnvironmentBuilder.mergeEnvironments(environment,
113: defaultEnvironment);
114: }
115: }
116:
117: public void build(XmlObject container,
118: DeploymentContext applicationContext,
119: DeploymentContext moduleContext) throws DeploymentException {
120: GerClusteringWadiType clusteringWadiType = getWadiClusterConfig(container);
121: if (clusteringWadiType != null) {
122: GBeanData webModuleData = extractWebModule(moduleContext);
123: try {
124: AbstractName sessionManagerName = addSessionManager(
125: clusteringWadiType, webModuleData,
126: moduleContext);
127: addSessionHandlerFactory(moduleContext, webModuleData,
128: sessionManagerName);
129: addPreHandlerFactory(moduleContext, webModuleData,
130: sessionManagerName);
131: } catch (GBeanAlreadyExistsException e) {
132: throw new DeploymentException("Duplicate GBean", e);
133: }
134: }
135: }
136:
137: protected GBeanData extractWebModule(DeploymentContext moduleContext)
138: throws DeploymentException {
139: Configuration configuration = moduleContext.getConfiguration();
140: AbstractNameQuery webModuleQuery = new AbstractNameQuery(
141: configuration.getId(), Collections.EMPTY_MAP,
142: Collections.singleton(JettyWebAppContext.class
143: .getName()));
144: try {
145: return configuration.findGBeanData(webModuleQuery);
146: } catch (GBeanNotFoundException e) {
147: throw new DeploymentException(
148: "Could not locate web module gbean in web app configuration",
149: e);
150: }
151: }
152:
153: public QNameSet getSpecQNameSet() {
154: return QNameSet.EMPTY;
155: }
156:
157: public QNameSet getPlanQNameSet() {
158: return CLUSTERING_WADI_QNAME_SET;
159: }
160:
161: protected GerClusteringWadiType getWadiClusterConfig(
162: XmlObject container) throws DeploymentException {
163: XmlObject[] items = container
164: .selectChildren(CLUSTERING_WADI_QNAME_SET);
165: if (items.length > 1) {
166: throw new DeploymentException(
167: "Unexpected count of clustering elements in geronimo plan "
168: + items.length + " qnameset: "
169: + CLUSTERING_WADI_QNAME_SET);
170: }
171: if (items.length == 1) {
172: return (GerClusteringWadiType) items[0].copy().changeType(
173: GerClusteringWadiType.type);
174: }
175: return null;
176: }
177:
178: protected AbstractName addSessionManager(
179: GerClusteringWadiType clustering, GBeanData webModuleData,
180: DeploymentContext moduleContext)
181: throws GBeanAlreadyExistsException {
182: AbstractName name = moduleContext.getNaming().createChildName(
183: moduleContext.getModuleName(), "WADISessionManager",
184: NameFactory.GERONIMO_SERVICE);
185:
186: GBeanData beanData = new GBeanData(name,
187: BasicWADISessionManager.GBEAN_INFO);
188:
189: setConfigInfo(clustering, webModuleData, beanData);
190: setCluster(clustering, beanData);
191: setBackingStrategyFactory(clustering, beanData);
192:
193: moduleContext.addGBean(beanData);
194:
195: return name;
196: }
197:
198: protected void setConfigInfo(GerClusteringWadiType clustering,
199: GBeanData webModuleData, GBeanData beanData) {
200: int sweepInterval = getSweepInterval(clustering);
201: int numPartitions = getNumberOfPartitions(clustering);
202: Integer sessionTimeout = getSessionTimeout(webModuleData);
203: boolean disableReplication = isDisableReplication(clustering);
204: boolean deltaReplication = isDeltaReplication(clustering);
205:
206: String contextPath = (String) webModuleData
207: .getAttribute("contextPath");
208: URI serviceSpaceName;
209: try {
210: serviceSpaceName = new URI(contextPath);
211: } catch (URISyntaxException e) {
212: throw (AssertionError) new AssertionError("contextPath ["
213: + contextPath + "] cannot be parsed as an URI.")
214: .initCause(e);
215: }
216:
217: WADISessionManagerConfigInfo configInfo = new WADISessionManagerConfigInfo(
218: serviceSpaceName, sweepInterval, numPartitions,
219: sessionTimeout.intValue(), disableReplication,
220: deltaReplication);
221: beanData.setAttribute(
222: BasicWADISessionManager.GBEAN_ATTR_WADI_CONFIG_INFO,
223: configInfo);
224: }
225:
226: protected Integer getSessionTimeout(GBeanData webModuleData)
227: throws AssertionError {
228: Integer sessionTimeout = (Integer) webModuleData
229: .getAttribute(JettyWebAppContext.GBEAN_ATTR_SESSION_TIMEOUT);
230: if (null == sessionTimeout) {
231: throw new AssertionError();
232: }
233: return sessionTimeout;
234: }
235:
236: protected boolean isDeltaReplication(
237: GerClusteringWadiType clustering) {
238: if (clustering.isSetDeltaReplication()) {
239: return clustering.getDeltaReplication();
240: }
241: return false;
242: }
243:
244: protected boolean isDisableReplication(
245: GerClusteringWadiType clustering) {
246: if (clustering.isSetDisableReplication()) {
247: return clustering.getDisableReplication();
248: }
249: return false;
250: }
251:
252: protected int getNumberOfPartitions(GerClusteringWadiType clustering) {
253: if (clustering.isSetNumPartitions()) {
254: return clustering.getNumPartitions().intValue();
255: }
256: return defaultNumPartitions;
257: }
258:
259: protected int getSweepInterval(GerClusteringWadiType clustering) {
260: if (clustering.isSetSweepInterval()) {
261: return clustering.getSweepInterval().intValue();
262: }
263: return defaultSweepInterval;
264: }
265:
266: protected void setCluster(GerClusteringWadiType clustering,
267: GBeanData beanData) {
268: Set patterns = new HashSet();
269: if (clustering.isSetCluster()) {
270: addAbstractNameQueries(patterns, clustering.getCluster()
271: .getPatternArray());
272: } else {
273: patterns.add(defaultClusterName);
274: }
275: beanData.setReferencePatterns(
276: BasicWADISessionManager.GBEAN_REF_CLUSTER, patterns);
277: }
278:
279: protected void setBackingStrategyFactory(
280: GerClusteringWadiType clustering, GBeanData beanData) {
281: Set patterns = new HashSet();
282: if (clustering.isSetBackingStrategyFactory()) {
283: addAbstractNameQueries(patterns, clustering
284: .getBackingStrategyFactory().getPatternArray());
285: } else {
286: patterns.add(defaultBackingStrategyFactoryName);
287: }
288: beanData
289: .setReferencePatterns(
290: BasicWADISessionManager.GBEAN_REF_BACKING_STRATEGY_FACTORY,
291: patterns);
292: }
293:
294: protected AbstractName addPreHandlerFactory(
295: DeploymentContext moduleContext, GBeanData webModuleData,
296: AbstractName sessionManagerName)
297: throws GBeanAlreadyExistsException {
298: AbstractName name = moduleContext.getNaming().createChildName(
299: moduleContext.getModuleName(),
300: "WADIClusteredPreHandlerFactory",
301: NameFactory.GERONIMO_SERVICE);
302:
303: GBeanData beanData = new GBeanData(name,
304: WADIClusteredPreHandlerFactory.GBEAN_INFO);
305: beanData
306: .setReferencePattern(
307: WADIClusteredPreHandlerFactory.GBEAN_REF_WADI_SESSION_MANAGER,
308: sessionManagerName);
309:
310: webModuleData.setReferencePattern(
311: JettyWebAppContext.GBEAN_REF_PRE_HANDLER_FACTORY, name);
312:
313: moduleContext.addGBean(beanData);
314:
315: return name;
316: }
317:
318: protected AbstractName addSessionHandlerFactory(
319: DeploymentContext moduleContext, GBeanData webModuleData,
320: AbstractName sessionManagerName)
321: throws GBeanAlreadyExistsException {
322: AbstractName name = moduleContext.getNaming().createChildName(
323: moduleContext.getModuleName(),
324: "ClusteredSessionHandlerFactory",
325: NameFactory.GERONIMO_SERVICE);
326:
327: GBeanData beanData = new GBeanData(name,
328: ClusteredSessionHandlerFactory.GBEAN_INFO);
329: beanData
330: .setReferencePattern(
331: ClusteredSessionHandlerFactory.GBEAN_REF_SESSION_MANAGER,
332: sessionManagerName);
333:
334: webModuleData.setReferencePattern(
335: JettyWebAppContext.GBEAN_REF_SESSION_HANDLER_FACTORY,
336: name);
337:
338: moduleContext.addGBean(beanData);
339:
340: return name;
341: }
342:
343: protected void addAbstractNameQueries(Set patterns,
344: GerPatternType[] patternTypes) {
345: for (int i = 0; i < patternTypes.length; i++) {
346: AbstractNameQuery query = ENCConfigBuilder
347: .buildAbstractNameQuery(patternTypes[i], null,
348: null, null);
349: patterns.add(query);
350: }
351: }
352:
353: public static final GBeanInfo GBEAN_INFO;
354:
355: public static final String GBEAN_ATTR_DFT_SWEEP_INTERVAL = "defaultSweepInterval";
356: public static final String GBEAN_ATTR_DFT_NUM_PARTITIONS = "defaultNumPartitions";
357: public static final String GBEAN_ATTR_DFT_BACKING_STRATEGY_FACTORY_NAME = "defaultBackingStrategyFactoryName";
358: public static final String GBEAN_ATTR_DFT_CLUSTER_NAME = "defaultClusterName";
359: public static final String GBEAN_ATTR_DFT_ENVIRONMENT = "defaultEnvironment";
360:
361: static {
362: GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(
363: "WADI Session Manager",
364: WADIJettyClusteringBuilder.class,
365: NameFactory.MODULE_BUILDER);
366:
367: infoBuilder.addAttribute(GBEAN_ATTR_DFT_SWEEP_INTERVAL,
368: int.class, true);
369: infoBuilder.addAttribute(GBEAN_ATTR_DFT_NUM_PARTITIONS,
370: int.class, true);
371: infoBuilder.addAttribute(
372: GBEAN_ATTR_DFT_BACKING_STRATEGY_FACTORY_NAME,
373: AbstractNameQuery.class, true);
374: infoBuilder.addAttribute(GBEAN_ATTR_DFT_CLUSTER_NAME,
375: AbstractNameQuery.class, true);
376: infoBuilder.addAttribute(GBEAN_ATTR_DFT_ENVIRONMENT,
377: Environment.class, true);
378:
379: infoBuilder
380: .setConstructor(new String[] {
381: GBEAN_ATTR_DFT_SWEEP_INTERVAL,
382: GBEAN_ATTR_DFT_NUM_PARTITIONS,
383: GBEAN_ATTR_DFT_BACKING_STRATEGY_FACTORY_NAME,
384: GBEAN_ATTR_DFT_CLUSTER_NAME,
385: GBEAN_ATTR_DFT_ENVIRONMENT });
386:
387: GBEAN_INFO = infoBuilder.getBeanInfo();
388: }
389:
390: public static GBeanInfo getGBeanInfo() {
391: return GBEAN_INFO;
392: }
393:
394: }
|