001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.geronimo.farm.deployment;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.io.OutputStream;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027: import java.util.ArrayList;
028: import java.util.Collections;
029: import java.util.LinkedHashSet;
030: import java.util.List;
031: import java.util.Set;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.apache.geronimo.farm.config.ClusterInfo;
036: import org.apache.geronimo.farm.config.NodeInfo;
037: import org.apache.geronimo.gbean.AbstractName;
038: import org.apache.geronimo.gbean.GBeanData;
039: import org.apache.geronimo.gbean.GBeanInfo;
040: import org.apache.geronimo.gbean.GBeanInfoBuilder;
041: import org.apache.geronimo.kernel.Kernel;
042: import org.apache.geronimo.kernel.config.ConfigurationAlreadyExistsException;
043: import org.apache.geronimo.kernel.config.ConfigurationData;
044: import org.apache.geronimo.kernel.config.ConfigurationInfo;
045: import org.apache.geronimo.kernel.config.ConfigurationModuleType;
046: import org.apache.geronimo.kernel.config.ConfigurationStore;
047: import org.apache.geronimo.kernel.config.InvalidConfigException;
048: import org.apache.geronimo.kernel.config.NoSuchConfigException;
049: import org.apache.geronimo.kernel.repository.Artifact;
050: import org.apache.geronimo.kernel.repository.Environment;
051: import org.apache.geronimo.kernel.repository.WritableListableRepository;
052: import org.apache.geronimo.system.configuration.RepositoryConfigurationStore;
053:
054: /**
055: *
056: * @version $Rev:$ $Date:$
057: */
058: public class MasterConfigurationStore implements ConfigurationStore {
059: private static final Log log = LogFactory
060: .getLog(MasterConfigurationStore.class);
061:
062: private final ConfigurationStore delegate;
063: private final Environment defaultEnvironment;
064: private final ClusterInfo clusterInfo;
065: private final AbstractName clusterInfoName;
066: private final ClusterConfigurationStoreClient storeDelegate;
067: private final SlaveConfigurationNameBuilder slaveConfigNameBuilder;
068:
069: public MasterConfigurationStore(Kernel kernel, String objectName,
070: AbstractName abstractName,
071: WritableListableRepository repository,
072: Environment defaultEnvironment, ClusterInfo clusterInfo,
073: ClusterConfigurationStoreClient storeDelegate) {
074: if (null == kernel) {
075: throw new IllegalArgumentException("kernel is required");
076: } else if (null == objectName) {
077: throw new IllegalArgumentException("objectName is required");
078: } else if (null == repository) {
079: throw new IllegalArgumentException("repository is required");
080: } else if (null == defaultEnvironment) {
081: throw new IllegalArgumentException(
082: "defaultEnvironment is required");
083: } else if (null == clusterInfo) {
084: throw new IllegalArgumentException(
085: "clusterInfo is required");
086: } else if (null == storeDelegate) {
087: throw new IllegalArgumentException(
088: "storeDelegate is required");
089: }
090: this .defaultEnvironment = defaultEnvironment;
091: this .clusterInfo = clusterInfo;
092: this .storeDelegate = storeDelegate;
093:
094: slaveConfigNameBuilder = newSlaveConfigurationNameBuilder();
095: clusterInfoName = kernel.getAbstractNameFor(clusterInfo);
096: delegate = newConfigurationStore(kernel, objectName,
097: abstractName, repository);
098: }
099:
100: public boolean containsConfiguration(Artifact configId) {
101: if (slaveConfigNameBuilder.isSlaveConfigurationName(configId)) {
102: return false;
103: }
104: return delegate.containsConfiguration(configId);
105: }
106:
107: public File createNewConfigurationDir(Artifact configId)
108: throws ConfigurationAlreadyExistsException {
109: Artifact slaveConfigId = slaveConfigNameBuilder
110: .buildSlaveConfigurationName(configId);
111: return delegate.createNewConfigurationDir(slaveConfigId);
112: }
113:
114: public void exportConfiguration(Artifact configId,
115: OutputStream output) throws IOException,
116: NoSuchConfigException {
117: ensureArtifactForMasterConfiguration(configId);
118: delegate.exportConfiguration(configId, output);
119: }
120:
121: public AbstractName getAbstractName() {
122: return delegate.getAbstractName();
123: }
124:
125: public String getObjectName() {
126: return delegate.getObjectName();
127: }
128:
129: public void install(ConfigurationData configurationData)
130: throws IOException, InvalidConfigException {
131: Environment environment = configurationData.getEnvironment();
132: Artifact actualConfigId = environment.getConfigId();
133: Artifact slaveConfigId = slaveConfigNameBuilder
134: .buildSlaveConfigurationName(actualConfigId);
135: environment.setConfigId(slaveConfigId);
136:
137: storeDelegate.install(clusterInfo, configurationData);
138: installSlaveConfiguration(configurationData);
139:
140: environment.setConfigId(actualConfigId);
141:
142: installMasterConfiguration(configurationData, slaveConfigId);
143: }
144:
145: public boolean isInPlaceConfiguration(Artifact configId)
146: throws NoSuchConfigException, IOException {
147: ensureArtifactForMasterConfiguration(configId);
148: return false;
149: }
150:
151: public List<ConfigurationInfo> listConfigurations() {
152: List<ConfigurationInfo> configurationInfos = delegate
153: .listConfigurations();
154:
155: List<ConfigurationInfo> filteredConfigurationInfos = new ArrayList<ConfigurationInfo>();
156: for (ConfigurationInfo configurationInfo : configurationInfos) {
157: if (!slaveConfigNameBuilder
158: .isSlaveConfigurationName(configurationInfo
159: .getConfigID())) {
160: filteredConfigurationInfos.add(configurationInfo);
161: }
162: }
163:
164: return filteredConfigurationInfos;
165: }
166:
167: public ConfigurationData loadConfiguration(Artifact configId)
168: throws NoSuchConfigException, IOException,
169: InvalidConfigException {
170: ensureArtifactForMasterConfiguration(configId);
171: return delegate.loadConfiguration(configId);
172: }
173:
174: public Set<URL> resolve(Artifact configId, String moduleName,
175: String path) throws NoSuchConfigException,
176: MalformedURLException {
177: ensureArtifactForMasterConfiguration(configId);
178: return delegate.resolve(configId, moduleName, path);
179: }
180:
181: public void uninstall(Artifact configId)
182: throws NoSuchConfigException, IOException {
183: ensureArtifactForMasterConfiguration(configId);
184:
185: Artifact slaveConfigId = slaveConfigNameBuilder
186: .buildSlaveConfigurationName(configId);
187: storeDelegate.uninstall(clusterInfo, slaveConfigId);
188:
189: try {
190: delegate.uninstall(slaveConfigId);
191: } catch (Exception e) {
192: log.warn("Exception when uninstalling [" + slaveConfigId
193: + "]", e);
194: }
195: delegate.uninstall(configId);
196: }
197:
198: protected void ensureArtifactForMasterConfiguration(
199: Artifact configId) throws NoSuchConfigException {
200: if (slaveConfigNameBuilder.isSlaveConfigurationName(configId)) {
201: throw new NoSuchConfigException(configId);
202: }
203: }
204:
205: protected ConfigurationStore newConfigurationStore(Kernel kernel,
206: String objectName, AbstractName abstractName,
207: WritableListableRepository repository) {
208: return new RepositoryConfigurationStore(kernel, objectName,
209: abstractName, repository);
210: }
211:
212: protected SlaveConfigurationNameBuilder newSlaveConfigurationNameBuilder() {
213: return new BasicSlaveConfigurationNameBuilder();
214: }
215:
216: protected void installMasterConfiguration(
217: ConfigurationData configurationData, Artifact slaveConfigId)
218: throws IOException, InvalidConfigException {
219: ConfigurationData masterConfigurationData = buildMasterConfigurationData(
220: configurationData, slaveConfigId);
221: try {
222: delegate.install(masterConfigurationData);
223: } catch (Exception e) {
224: storeDelegate.uninstall(clusterInfo, slaveConfigId);
225: try {
226: delegate.uninstall(slaveConfigId);
227: } catch (NoSuchConfigException nestedE) {
228: }
229: if (e instanceof IOException) {
230: throw (IOException) e;
231: } else if (e instanceof InvalidConfigException) {
232: throw (InvalidConfigException) e;
233: }
234: throw (IOException) new IOException("See nested")
235: .initCause(e);
236: }
237: }
238:
239: protected void installSlaveConfiguration(
240: ConfigurationData configurationData) throws IOException,
241: InvalidConfigException {
242: try {
243: delegate.install(configurationData);
244: } catch (Exception e) {
245: storeDelegate.uninstall(clusterInfo, configurationData
246: .getId());
247: if (e instanceof IOException) {
248: throw (IOException) e;
249: } else if (e instanceof InvalidConfigException) {
250: throw (InvalidConfigException) e;
251: }
252: throw (IOException) new IOException("See nested")
253: .initCause(e);
254: }
255: }
256:
257: protected ConfigurationData buildMasterConfigurationData(
258: ConfigurationData configurationData, Artifact slaveConfigId) {
259: Environment environment = buildEnvironment(configurationData);
260:
261: Artifact configId = environment.getConfigId();
262:
263: List<GBeanData> gbeans = buildControllerGBeans(configId,
264: slaveConfigId);
265:
266: File configurationDir = delegate
267: .createNewConfigurationDir(configId);
268:
269: return new ConfigurationData(ConfigurationModuleType.CAR,
270: new LinkedHashSet(), gbeans, Collections.EMPTY_MAP,
271: environment, configurationDir, null, configurationData
272: .getNaming());
273: }
274:
275: protected Environment buildEnvironment(
276: ConfigurationData configurationData) {
277: Environment environment = new Environment(defaultEnvironment);
278: environment.setConfigId(configurationData.getId());
279: return environment;
280: }
281:
282: protected List<GBeanData> buildControllerGBeans(Artifact configId,
283: Artifact slaveConfigId) {
284: List<GBeanData> gbeans = new ArrayList<GBeanData>();
285: for (NodeInfo nodeInfo : clusterInfo.getNodeInfos()) {
286: GBeanData gbean = buildControllerGBean(configId, nodeInfo,
287: slaveConfigId);
288: gbeans.add(gbean);
289: }
290: return gbeans;
291: }
292:
293: protected GBeanData buildControllerGBean(Artifact configId,
294: NodeInfo nodeInfo, Artifact slaveConfigId) {
295: AbstractName controllerName = buildControllerName(configId,
296: nodeInfo);
297:
298: GBeanData gbean = new GBeanData(controllerName,
299: BasicClusterConfigurationController.GBEAN_INFO);
300: gbean
301: .setAttribute(
302: BasicClusterConfigurationController.GBEAN_ATTR_ARTIFACT,
303: slaveConfigId);
304: gbean
305: .setAttribute(
306: BasicClusterConfigurationController.GBEAN_ATTR_IGNORE_START_CONF_FAIL_UPON_START,
307: Boolean.TRUE);
308: gbean
309: .setAttribute(
310: BasicClusterConfigurationController.GBEAN_ATTR_NODE_NAME,
311: nodeInfo.getName());
312: gbean
313: .setAttribute(
314: BasicClusterConfigurationController.GBEAN_ATTR_START_CONF_UPON_START,
315: Boolean.TRUE);
316: gbean
317: .setReferencePattern(
318: BasicClusterConfigurationController.GBEAN_REF_CLUSTER_INFO,
319: clusterInfoName);
320: return gbean;
321: }
322:
323: protected AbstractName buildControllerName(Artifact configId,
324: NodeInfo nodeInfo) {
325: return new AbstractName(configId, Collections.singletonMap(
326: "nodeName", nodeInfo.getName()));
327: }
328:
329: public static final GBeanInfo GBEAN_INFO;
330:
331: public static final String GBEAN_J2EE_TYPE = "ConfigurationStore";
332: public static final String GBEAN_ATTR_KERNEL = "kernel";
333: public static final String GBEAN_ATTR_OBJECT_NAME = "objectName";
334: public static final String GBEAN_ATTR_DEFAULT_ENV = "defaultEnvironment";
335: public static final String GBEAN_REF_REPOSITORY = "Repository";
336: public static final String GBEAN_REF_CLUSTER_INFO = "ClusterInfo";
337: public static final String GBEAN_REF_CLUSTER_CONF_STORE_CLIENT = "ClusterConfigurationStoreClient";
338:
339: static {
340: GBeanInfoBuilder builder = GBeanInfoBuilder.createStatic(
341: MasterConfigurationStore.class, GBEAN_J2EE_TYPE);
342:
343: builder.addAttribute(GBEAN_ATTR_KERNEL, Kernel.class, false);
344: builder.addAttribute(GBEAN_ATTR_OBJECT_NAME, String.class,
345: false);
346: builder.addAttribute("abstractName", AbstractName.class, false);
347: builder.addAttribute(GBEAN_ATTR_DEFAULT_ENV, Environment.class,
348: true, true);
349:
350: builder.addReference(GBEAN_REF_REPOSITORY,
351: WritableListableRepository.class, "Repository");
352: builder.addReference(GBEAN_REF_CLUSTER_INFO, ClusterInfo.class);
353: builder.addReference(GBEAN_REF_CLUSTER_CONF_STORE_CLIENT,
354: ClusterConfigurationStoreClient.class);
355:
356: builder.addInterface(ConfigurationStore.class);
357:
358: builder.setConstructor(new String[] { GBEAN_ATTR_KERNEL,
359: GBEAN_ATTR_OBJECT_NAME, "abstractName",
360: GBEAN_REF_REPOSITORY, GBEAN_ATTR_DEFAULT_ENV,
361: GBEAN_REF_CLUSTER_INFO,
362: GBEAN_REF_CLUSTER_CONF_STORE_CLIENT });
363:
364: GBEAN_INFO = builder.getBeanInfo();
365: }
366:
367: public static GBeanInfo getGBeanInfo() {
368: return GBEAN_INFO;
369: }
370:
371: }
|