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 */
017 package org.apache.servicemix.jbi.container;
018
019 import java.io.File;
020 import java.io.IOException;
021 import java.util.Map;
022 import java.util.concurrent.ConcurrentHashMap;
023 import java.util.concurrent.atomic.AtomicBoolean;
024
025 import javax.jbi.JBIException;
026
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.apache.servicemix.jbi.framework.ComponentMBeanImpl;
030 import org.apache.servicemix.jbi.management.BaseSystemService;
031 import org.apache.servicemix.jbi.util.FileUtil;
032 import org.apache.servicemix.jbi.util.FileVersionUtil;
033
034 /**
035 * Holder for environment information
036 *
037 * <component-name> (component root dir)
038 * |-> version_X (versionned dir)
039 * \-> workspace (workspace dir)
040 *
041 * ServiceAssembly root
042 * \-> version_X (versionned dir)
043 * |-> install (unzip dir)
044 * \-> sus (service units dir)
045 * |-> <component-name>
046 * |-> <service-unit-name>
047 *
048 * @version $Revision: 564900 $
049 */
050 public class EnvironmentContext extends BaseSystemService implements EnvironmentContextMBean {
051
052 private static final Log LOG = LogFactory.getLog(EnvironmentContext.class);
053
054 private File jbiRootDir;
055 private File componentsDir;
056 private File installationDir;
057 private File deploymentDir;
058 private File sharedLibDir;
059 private File serviceAssembliesDir;
060 private File tmpDir;
061 private Map envMap = new ConcurrentHashMap();
062 private AtomicBoolean started = new AtomicBoolean(false);
063
064 /**
065 * @return the current version of servicemix
066 */
067 public static String getVersion() {
068 String answer = null;
069 Package p = Package.getPackage("org.apache.servicemix");
070 if (p != null) {
071 answer = p.getImplementationVersion();
072 }
073 return answer;
074 }
075
076 /**
077 * Get Description
078 * @return description
079 */
080 public String getDescription() {
081 return "Manages Environment for the Container";
082 }
083
084 /**
085 * @return Returns the componentsDir.
086 */
087 public File getComponentsDir() {
088 return componentsDir;
089 }
090
091 /**
092 * @return Returns the installationDir.
093 */
094 public File getInstallationDir() {
095 return installationDir;
096 }
097
098 /**
099 * Set the installationDir - rge default location
100 * is root/<container name>/installation
101 * @param installationDir
102 */
103 public void setInstallationDir(File installationDir) {
104 this.installationDir = installationDir;
105 }
106
107 /**
108 * @return Returns the deploymentDir.
109 */
110 public File getDeploymentDir() {
111 return deploymentDir;
112 }
113
114 /**
115 * @param deploymentDir The deploymentDir to set.
116 */
117 public void setDeploymentDir(File deploymentDir) {
118 this.deploymentDir = deploymentDir;
119 }
120
121 /**
122 *
123 * @return Returns the shared library directory
124 */
125 public File getSharedLibDir() {
126 return sharedLibDir;
127 }
128
129 /**
130 * @return Returns the tmpDir
131 */
132 public File getTmpDir() {
133 if (tmpDir != null) {
134 FileUtil.buildDirectory(tmpDir);
135 }
136 return tmpDir;
137 }
138
139 /**
140 * @return Returns service asseblies directory
141 */
142 public File getServiceAssembliesDir() {
143 return serviceAssembliesDir;
144 }
145
146 /**
147 * Initialize the Environment
148 *
149 * @param container
150 * @param rootDirPath
151 * @exception javax.jbi.JBIException if the root directory informed could not be created or it is not a directory
152 */
153 public void init(JBIContainer container, String rootDirPath) throws JBIException {
154 super.init(container);
155 jbiRootDir = new File(rootDirPath);
156 buildDirectoryStructure();
157 }
158
159 protected Class getServiceMBean() {
160 return EnvironmentContextMBean.class;
161 }
162
163 /**
164 * Start the item.
165 *
166 * @exception javax.jbi.JBIException if the item fails to start.
167 */
168 public void start() throws javax.jbi.JBIException {
169 if (started.compareAndSet(false, true)) {
170 super.start();
171 }
172 }
173
174 /**
175 * Stop the item. This suspends current messaging activities.
176 *
177 * @exception javax.jbi.JBIException if the item fails to stop.
178 */
179 public void stop() throws javax.jbi.JBIException {
180 if (started.compareAndSet(true, false)) {
181 super.stop();
182 }
183 }
184
185 /**
186 * Shut down the item. The releases resources, preparatory to uninstallation.
187 *
188 * @exception javax.jbi.JBIException if the item fails to shut down.
189 */
190 public void shutDown() throws javax.jbi.JBIException {
191 super.shutDown();
192 envMap.clear();
193 container.getManagementContext().unregisterMBean(this);
194 }
195
196 /**
197 * register the ComponentConnector
198 *
199 * @param connector
200 * @return the CompponentEnvironment
201 * @throws JBIException
202 */
203 public ComponentEnvironment registerComponent(ComponentMBeanImpl connector) throws JBIException {
204 return registerComponent(null, connector);
205 }
206
207 /**
208 * register the ComponentConnector
209 *
210 * @param connector
211 * @return the CompponentEnvironment
212 * @throws JBIException
213 */
214 public ComponentEnvironment registerComponent(ComponentEnvironment result, ComponentMBeanImpl connector) throws JBIException {
215 if (result == null) {
216 result = new ComponentEnvironment();
217 }
218 if (!connector.isPojo()) {
219 if (container.isEmbedded()) {
220 throw new JBIException("JBI component can not be installed in embedded mode");
221 }
222 // add workspace root and stats root ..
223 try {
224 String name = connector.getComponentNameSpace().getName();
225 if (result.getComponentRoot() == null) {
226 File componentRoot = getComponentRootDir(name);
227 FileUtil.buildDirectory(componentRoot);
228 result.setComponentRoot(componentRoot);
229 }
230 if (result.getWorkspaceRoot() == null) {
231 File privateWorkspace = createWorkspaceDirectory(name);
232 result.setWorkspaceRoot(privateWorkspace);
233 }
234 if (result.getStateFile() == null) {
235 File stateFile = FileUtil.getDirectoryPath(result.getComponentRoot(), "state.xml");
236 result.setStateFile(stateFile);
237 }
238 } catch (IOException e) {
239 throw new JBIException(e);
240 }
241 }
242 result.setLocalConnector(connector);
243 envMap.put(connector, result);
244 return result;
245 }
246
247 /**
248 * Get root directory for a Component
249 *
250 * @param componentName
251 * @return directory for deployment/workspace etc
252 * @throws IOException
253 */
254 public File getComponentRootDir(String componentName) {
255 if (getComponentsDir() == null) {
256 return null;
257 }
258 return FileUtil.getDirectoryPath(getComponentsDir(), componentName);
259 }
260
261 /**
262 * Create root directory for a Component
263 *
264 * @param componentName
265 * @return directory for deployment/workspace etc
266 * @throws IOException
267 */
268 public File createComponentRootDir(String componentName) throws IOException {
269 if (getComponentsDir() == null) {
270 return null;
271 }
272 return FileUtil.getDirectoryPath(getComponentsDir(), componentName);
273 }
274
275 /**
276 * Get a new versionned directory for installation
277 *
278 * @param componentName
279 * @return
280 * @throws IOException
281 */
282 public File getNewComponentInstallationDir(String componentName) throws IOException {
283 File result = getComponentRootDir(componentName);
284 // get new version dir
285 return FileVersionUtil.getNewVersionDirectory(result);
286 }
287
288 /**
289 * Create installation directory for a Component
290 *
291 * @param componentName
292 * @return directory to deploy in
293 * @throws IOException
294 */
295 public File getComponentInstallationDir(String componentName) throws IOException {
296 File result = getComponentRootDir(componentName);
297 // get the version directory
298 return FileVersionUtil.getLatestVersionDirectory(result);
299 }
300
301 public ComponentEnvironment getNewComponentEnvironment(String compName) throws IOException {
302 File rootDir = FileUtil.getDirectoryPath(getComponentsDir(), compName);
303 File instDir = FileVersionUtil.getNewVersionDirectory(rootDir);
304 File workDir = FileUtil.getDirectoryPath(rootDir, "workspace");
305 File stateFile = FileUtil.getDirectoryPath(rootDir, "state.xml");
306 ComponentEnvironment env = new ComponentEnvironment();
307 env.setComponentRoot(rootDir);
308 env.setInstallRoot(instDir);
309 env.setWorkspaceRoot(workDir);
310 env.setStateFile(stateFile);
311 return env;
312 }
313
314 public ComponentEnvironment getComponentEnvironment(String compName) throws IOException {
315 File rootDir = FileUtil.getDirectoryPath(getComponentsDir(), compName);
316 File instDir = FileVersionUtil.getLatestVersionDirectory(rootDir);
317 File workDir = FileUtil.getDirectoryPath(rootDir, "workspace");
318 File stateFile = FileUtil.getDirectoryPath(rootDir, "state.xml");
319 ComponentEnvironment env = new ComponentEnvironment();
320 env.setComponentRoot(rootDir);
321 env.setInstallRoot(instDir);
322 env.setWorkspaceRoot(workDir);
323 env.setStateFile(stateFile);
324 return env;
325 }
326
327 public ServiceAssemblyEnvironment getNewServiceAssemblyEnvironment(String saName) throws IOException {
328 File rootDir = FileUtil.getDirectoryPath(getServiceAssembliesDir(), saName);
329 File versDir = FileVersionUtil.getNewVersionDirectory(rootDir);
330 File instDir = FileUtil.getDirectoryPath(versDir, "install");
331 File susDir = FileUtil.getDirectoryPath(versDir, "sus");
332 File stateFile = FileUtil.getDirectoryPath(rootDir, "state.xml");
333 ServiceAssemblyEnvironment env = new ServiceAssemblyEnvironment();
334 env.setRootDir(rootDir);
335 env.setInstallDir(instDir);
336 env.setSusDir(susDir);
337 env.setStateFile(stateFile);
338 return env;
339 }
340
341 public ServiceAssemblyEnvironment getServiceAssemblyEnvironment(String saName) {
342 File rootDir = FileUtil.getDirectoryPath(getServiceAssembliesDir(), saName);
343 File versDir = FileVersionUtil.getLatestVersionDirectory(rootDir);
344 File instDir = FileUtil.getDirectoryPath(versDir, "install");
345 File susDir = FileUtil.getDirectoryPath(versDir, "sus");
346 File stateFile = FileUtil.getDirectoryPath(rootDir, "state.xml");
347 ServiceAssemblyEnvironment env = new ServiceAssemblyEnvironment();
348 env.setRootDir(rootDir);
349 env.setInstallDir(instDir);
350 env.setSusDir(susDir);
351 env.setStateFile(stateFile);
352 return env;
353 }
354
355 /**
356 * Create workspace directory for a Component
357 *
358 * @param componentName
359 * @return directory workspace
360 * @throws IOException
361 */
362 public File createWorkspaceDirectory(String componentName) throws IOException {
363 File result = FileUtil.getDirectoryPath(getComponentsDir(), componentName);
364 result = FileUtil.getDirectoryPath(result, "workspace");
365 FileUtil.buildDirectory(result);
366 return result;
367 }
368
369 /**
370 * deregister the ComponentConnector
371 *
372 * @param connector
373 * @param doDelete true if component is to be deleted
374 */
375 public void unreregister(ComponentMBeanImpl connector) {
376 this.envMap.remove(connector);
377 }
378
379 /**
380 * Remove the Component root directory from the local file system
381 *
382 * @param componentName
383 */
384 public void removeComponentRootDirectory(String componentName) {
385 File file = getComponentRootDir(componentName);
386 if (file != null) {
387 if (!FileUtil.deleteFile(file)) {
388 LOG.warn("Failed to remove directory structure for component [version]: " + componentName + " [" + file.getName() + ']');
389 } else {
390 LOG.info("Removed directory structure for component [version]: " + componentName + " [" + file.getName() + ']');
391 }
392 }
393 }
394
395 /**
396 * create a shared library directory
397 *
398 * @param name
399 * @return directory
400 * @throws IOException
401 */
402 public File createSharedLibraryDirectory(String name) {
403 File result = FileUtil.getDirectoryPath(getSharedLibDir(), name);
404 FileUtil.buildDirectory(result);
405 return result;
406 }
407
408 /**
409 * remove shared library directory
410 * @param name
411 * @throws IOException
412 */
413 public void removeSharedLibraryDirectory(String name) {
414 File result = FileUtil.getDirectoryPath(getSharedLibDir(), name);
415 FileUtil.deleteFile(result);
416 }
417
418 private void buildDirectoryStructure() throws JBIException {
419 // We want ServiceMix to be able to run embedded
420 // so do not create the directory structure if the root does not exist
421 if (container.isEmbedded()) {
422 return;
423 }
424 try {
425 jbiRootDir = jbiRootDir.getCanonicalFile();
426 if (!jbiRootDir.exists()) {
427 if (!jbiRootDir.mkdirs()) {
428 throw new JBIException("Directory could not be created: " + jbiRootDir.getCanonicalFile());
429 }
430 } else if (!jbiRootDir.isDirectory()) {
431 throw new JBIException("Not a directory: " + jbiRootDir.getCanonicalFile());
432 }
433 if (installationDir == null) {
434 installationDir = FileUtil.getDirectoryPath(jbiRootDir, "install");
435 }
436 installationDir = installationDir.getCanonicalFile();
437 if (deploymentDir == null) {
438 deploymentDir = FileUtil.getDirectoryPath(jbiRootDir, "deploy");
439 }
440 deploymentDir = deploymentDir.getCanonicalFile();
441 componentsDir = FileUtil.getDirectoryPath(jbiRootDir, "components").getCanonicalFile();
442 tmpDir = FileUtil.getDirectoryPath(jbiRootDir, "tmp").getCanonicalFile();
443 sharedLibDir = FileUtil.getDirectoryPath(jbiRootDir, "sharedlibs").getCanonicalFile();
444 serviceAssembliesDir = FileUtil.getDirectoryPath(jbiRootDir, "service-assemblies").getCanonicalFile();
445 //actually create the sub directories
446 FileUtil.buildDirectory(installationDir);
447 FileUtil.buildDirectory(deploymentDir);
448 FileUtil.buildDirectory(componentsDir);
449 FileUtil.buildDirectory(tmpDir);
450 FileUtil.buildDirectory(sharedLibDir);
451 FileUtil.buildDirectory(serviceAssembliesDir);
452 } catch (IOException e) {
453 throw new JBIException(e);
454 }
455 }
456
457 public File getJbiRootDir() {
458 return jbiRootDir;
459 }
460
461 }