/*******************************************************************************
* Copyright (c) 2011 GigaSpaces Technologies Ltd. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*******************************************************************************/
package org.cloudifysource.utilitydomain.context;
import java.io.File;
import java.util.Arrays;
import org.cloudifysource.domain.Service;
import org.cloudifysource.domain.context.ServiceContext;
import org.cloudifysource.dsl.internal.CloudifyConstants;
import org.cloudifysource.dsl.internal.DSLException;
import org.cloudifysource.dsl.internal.ServiceReader;
import org.cloudifysource.dsl.internal.packaging.PackagingException;
import org.cloudifysource.utilitydomain.admin.TimedAdmin;
import org.openspaces.core.cluster.ClusterInfo;
/***************
* A factory class used to set up a ServiceContext from external classes. This factory should never be used inside a
* service recipe - recipes already have the 'context' variable injected to them automatically. External Groovy scripts
* that require access to the CLoudify Service context may use this factory to access it. Using this factory inside a
* service file will not work, as it relies on environment variables that cloudify adds to commands it launches.
*
* @author barakme
*
*/
public final class ServiceContextFactory {
private static final java.util.logging.Logger logger = java.util.logging.Logger
.getLogger(ServiceContextFactory.class.getName());
private static TimedAdmin timedAdmin = null;
private static ServiceContext context = null;
/*****
* Private constructor to avoid initialization.
*/
private ServiceContextFactory() {
}
/****
* NEVER USE THIS INSIDE THE GSC. Should only be used by external scripts.
*
* @return A newly created service context.
*/
public static synchronized ServiceContext getServiceContext() {
if (context == null) {
// TODO - this code does not support setting a specific service file
// name
final ClusterInfo info = createClusterInfo();
final File dir = new File(".");
String serviceFileName = System.getenv(CloudifyConstants.USM_ENV_SERVICE_FILE_NAME);
if (serviceFileName == null) {
throw new IllegalStateException(
"Expected service file name in environment variable: "
+ CloudifyConstants.USM_ENV_SERVICE_FILE_NAME
+ " but got null. "
+ "The ServiceContextFactory can only be used from a script launched by a Cloudify "
+ " Service and will not run on its own");
}
final File dslFile = new File(dir,
serviceFileName);
Service service;
try {
service = ServiceReader.readService(dslFile);
} catch (PackagingException e) {
throw new IllegalArgumentException("Failed to read service", e);
} catch (DSLException e) {
throw new IllegalArgumentException("Failed to read service", e);
}
ServiceContextImpl newContext = new ServiceContextImpl(info, new File(".").getAbsolutePath());
// TODO - this code assumes running code only from a GSC. Test-recipe will not work here!
newContext.init(service, getTimedAdmin(), info);
context = newContext;
}
return context;
}
private static synchronized TimedAdmin getTimedAdmin() {
if (timedAdmin != null) {
logger.fine("using a cached instance of TimedAdmin");
return timedAdmin;
}
logger.fine("creating a new instance of TimedAdmin");
timedAdmin = new TimedAdmin();
timedAdmin.setStatisticsHistorySize(0);
logger.fine("Created new Admin Object with groups: " + Arrays.toString(timedAdmin.getAdminGroups())
+ " and Locators: " + Arrays.toString(timedAdmin.getAdminLocators()));
return timedAdmin;
}
private static ClusterInfo createClusterInfo() {
final ClusterInfo info = new ClusterInfo();
info.setInstanceId(getIntEnvironmentVariable(
CloudifyConstants.USM_ENV_INSTANCE_ID, 1));
info.setName(getEnvironmentVariable(
CloudifyConstants.USM_ENV_CLUSTER_NAME, "USM"));
info.setNumberOfInstances(getIntEnvironmentVariable(
CloudifyConstants.USM_ENV_NUMBER_OF_INSTANCES, 1));
return info;
}
private static String getEnvironmentVariable(final String name,
final String defaultValue) {
final String var = System.getenv(name);
if (var == null) {
logger.warning("Could not find environment variable: " + name
+ ". Using default value: " + defaultValue + " instead.");
return defaultValue;
}
return var;
}
private static int getIntEnvironmentVariable(final String name,
final int defaultValue) {
final String var = getEnvironmentVariable(name, "" + defaultValue);
try {
return Integer.parseInt(var);
} catch (final NumberFormatException nfe) {
logger.severe("Failed to parse integer environment variable: "
+ name + ". Value was: " + var + ". Using default value "
+ defaultValue + " instead");
return defaultValue;
}
}
}