blob: de388a2f4b9eecb1479c74c39803e376f8cc84b1 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* 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.apache.axis2.context;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.DependencyManager;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.util.SessionUtils;
import org.apache.axis2.util.UUIDGenerator;
import org.apache.axis2.util.threadpool.ThreadFactory;
import org.apache.axis2.util.threadpool.ThreadPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.net.URL;
import java.util.*;
/**
* This contains all the configuration information for Axis2.
*/
public class ConfigurationContext extends AbstractContext {
private static final Log log = LogFactory.getLog(ConfigurationContext.class);
/**
* Map containing <code>MessageID</code> to
* <code>OperationContext</code> mapping.
*/
private final Map operationContextMap = new HashMap();
private Hashtable serviceGroupContextMap = new Hashtable();
private Hashtable applicationSessionServiceGroupContextTable = new Hashtable();
private transient AxisConfiguration axisConfiguration;
private transient ThreadFactory threadPool;
//To keep TransportManager instance
private ListenerManager listenerManager;
// current time out interval is 30 secs. Need to make this configurable
private long serviceGroupContextTimoutInterval = 30 * 1000;
//To specify url mapping for services
private String contextRoot = "axis2";
private String servicePath = "services";
private String restPath = Constants.DEFAULT_REST_PATH;
//To have your own context path
public ConfigurationContext(AxisConfiguration axisConfiguration) {
super(null);
this.axisConfiguration = axisConfiguration;
initConfigContextTimeout(axisConfiguration);
}
private void initConfigContextTimeout(AxisConfiguration axisConfiguration) {
Parameter parameter = axisConfiguration.getParameter(Constants.Configuration.CONFIG_CONTEXT_TIMOUT_INTERVAL);
if (parameter != null) {
Object value = parameter.getValue();
if (value != null && value instanceof String) {
serviceGroupContextTimoutInterval = Integer.parseInt((String) value);
}
}
}
protected void finalize() throws Throwable {
super.finalize();
}
/**
* Searches for a ServiceGroupContext in the map with given id as the key.
* <pre>
* If(key != null && found)
* check for a service context for the intended service.
* if (!found)
* create one and hook up to ServiceGroupContext
* else
* create new ServiceGroupContext with the given key or if key is null with a new key
* create a new service context for the service
* </pre>
*
* @param messageContext
*/
public void fillServiceContextAndServiceGroupContext(
MessageContext messageContext)
throws AxisFault {
String serviceGroupContextId = messageContext.getServiceGroupContextId();
SessionContext sessionContext = messageContext.getSessionContext();
// by this time service group context id must have a value. Either from transport or from addressing
ServiceGroupContext serviceGroupContext;
ServiceContext serviceContext = messageContext.getServiceContext();
AxisService axisService = messageContext.getAxisService();
if (serviceContext == null) {
if (Constants.SCOPE_APPLICATION.equals(axisService.getScope())) {
String serviceGroupName = ((AxisServiceGroup) axisService.getParent()).getServiceGroupName();
serviceGroupContext = (ServiceGroupContext) applicationSessionServiceGroupContextTable.get(
serviceGroupName);
if (serviceGroupContext == null) {
AxisServiceGroup axisServiceGroup = messageContext.getAxisServiceGroup();
if (axisServiceGroup == null) {
axisServiceGroup = (AxisServiceGroup) messageContext.getAxisService().getParent();
}
serviceGroupContext = new ServiceGroupContext(messageContext.getConfigurationContext(),
axisServiceGroup);
applicationSessionServiceGroupContextTable.put(serviceGroupName, serviceGroupContext);
}
serviceContext = serviceGroupContext.getServiceContext(axisService);
} else if (!isNull(serviceGroupContextId)
&& (getServiceGroupContext(serviceGroupContextId, messageContext) != null)) {
// SGC is already there
serviceGroupContext =
getServiceGroupContext(serviceGroupContextId, messageContext);
serviceContext =
serviceGroupContext.getServiceContext(messageContext.getAxisService());
} else {
// either the key is null or no SGC is found from the give key
if (isNull(serviceGroupContextId)) {
serviceGroupContextId = UUIDGenerator.getUUID();
messageContext.setServiceGroupContextId(serviceGroupContextId);
}
if (messageContext.getAxisService() != null) {
AxisServiceGroup axisServiceGroup = (AxisServiceGroup) messageContext.getAxisService().getParent();
serviceGroupContext = new ServiceGroupContext(this, axisServiceGroup);
serviceContext = serviceGroupContext.getServiceContext(messageContext.getAxisService());
// set the serviceGroupContextID
serviceGroupContext.setId(serviceGroupContextId);
} else {
throw new AxisFault(Messages.getMessage("servicenotfound"));
}
}
/**
* 1. Check the max scope of the service group , if it is grater than TransportSession
* then need to store in configurationContext
* 2. Else need to store in SessionContext , and need to store both service context and
* service group context
*/
String maxScope = SessionUtils.calculateMaxScopeForServiceGroup(serviceGroupContext.getDescription());
if (Constants.SCOPE_SOAP_SESSION.equals(maxScope)) {
registerServiceGroupContext(serviceGroupContext);
} else if (Constants.SCOPE_TRANSPORT_SESSION.equals(maxScope)) {
if (sessionContext != null) {
sessionContext.addServiceGroupContext(serviceGroupContext, serviceGroupContextId);
sessionContext.addServiceContext(serviceContext);
}
}
messageContext.setServiceContext(serviceContext);
if (Constants.SCOPE_REQUEST.equals(maxScope)) {
messageContext.setServiceGroupContextId(null);
} else {
messageContext.setServiceGroupContext(serviceGroupContext);
}
}
if (sessionContext != null) {
// when you come here operation context MUST already been assigned to the message context
serviceContext.setProperty(HTTPConstants.COOKIE_STRING, sessionContext.getCookieID());
}
messageContext.getOperationContext().setParent(serviceContext);
}
/**
* Registers a OperationContext with a given message ID.
*
* @param messageID
* @param mepContext
*/
public synchronized void registerOperationContext(String messageID,
OperationContext mepContext) {
mepContext.setKey(messageID);
this.operationContextMap.put(messageID, mepContext);
}
public synchronized void registerServiceGroupContext(ServiceGroupContext serviceGroupContext) {
String id = serviceGroupContext.getId();
if (serviceGroupContextMap.get(id) == null) {
serviceGroupContextMap.put(id, serviceGroupContext);
serviceGroupContext.touch();
serviceGroupContext.setParent(this);
}
// this is the best time to clean up the SGCtxts since are not being used anymore
cleanupServiceGroupContexts();
}
public synchronized void addServiceGroupContextintoApplicatoionScopeTable(
ServiceGroupContext serviceGroupContext) {
applicationSessionServiceGroupContextTable.put(
serviceGroupContext.getDescription().getServiceGroupName(), serviceGroupContext);
}
public AxisConfiguration getAxisConfiguration() {
return axisConfiguration;
}
/**
* Gets a OperationContext given a Message ID.
*
* @return Returns OperationContext <code>OperationContext<code>
*/
public OperationContext getOperationContext(String id) {
return (OperationContext) this.operationContextMap.get(id);
}
public Map getOperationContextMap() {
return this.operationContextMap;
}
/**
* Allows users to resolve the path relative to the root diretory.
*
* @param path
*/
public File getRealPath(String path) {
URL repository = axisConfiguration.getRepository();
if (repository != null) {
File repo = new File(repository.getFile());
return new File(repo, path);
}
return null;
}
public synchronized ServiceGroupContext getServiceGroupContext(String serviceGroupContextId,
MessageContext msgContext) {
ServiceGroupContext serviceGroupContext = null;
if (serviceGroupContextMap != null) {
serviceGroupContext = (ServiceGroupContext) serviceGroupContextMap.get(serviceGroupContextId);
if (serviceGroupContext != null) {
serviceGroupContext.touch();
}
}
if (serviceGroupContext == null
&& msgContext != null
&& msgContext.getSessionContext() != null) {
serviceGroupContext = msgContext.getSessionContext().getServiceGroupContext(
serviceGroupContextId);
}
if (serviceGroupContext == null && msgContext != null) {
AxisService axisService = msgContext.getAxisService();
if (axisService != null) {
AxisServiceGroup asg = (AxisServiceGroup) axisService.getParent();
if (asg != null) {
serviceGroupContext = (ServiceGroupContext)
applicationSessionServiceGroupContextTable.get(asg.getServiceGroupName());
}
}
}
return serviceGroupContext;
}
/**
* Gets all service groups in the system.
*
* @return Returns hashmap of ServiceGroupContexts.
*/
public Hashtable getServiceGroupContexts() {
return serviceGroupContextMap;
}
/**
* Returns the thread factory.
*
* @return Returns configuration specific thread pool
*/
public ThreadFactory getThreadPool() {
if (threadPool == null) {
threadPool = new ThreadPool();
}
return threadPool;
}
private boolean isNull(String string) {
return "".equals(string) || (string == null);
}
/**
* @param configuration
*/
public void setAxisConfiguration(AxisConfiguration configuration) {
axisConfiguration = configuration;
}
/**
* Sets the thread factory.
*
* @param pool
*/
public void setThreadPool(ThreadFactory pool) throws AxisFault {
if (threadPool == null) {
threadPool = pool;
} else {
throw new AxisFault(Messages.getMessage("threadpoolset"));
}
}
private void cleanupServiceGroupContexts() {
synchronized (serviceGroupContextMap) {
long currentTime = new Date().getTime();
Iterator sgCtxtMapKeyIter = serviceGroupContextMap.keySet().iterator();
while (sgCtxtMapKeyIter.hasNext()) {
String sgCtxtId = (String) sgCtxtMapKeyIter.next();
ServiceGroupContext serviceGroupContext =
(ServiceGroupContext) serviceGroupContextMap.get(sgCtxtId);
if ((currentTime - serviceGroupContext.getLastTouchedTime()) >
getServiceGroupContextTimoutInterval()) {
sgCtxtMapKeyIter.remove();
cleanupServiceContexts(serviceGroupContext);
}
}
}
}
public ListenerManager getListenerManager() {
return listenerManager;
}
public void setTransportManager(ListenerManager listenerManager) {
this.listenerManager = listenerManager;
}
private void cleanupServiceContexts(ServiceGroupContext serviceGroupContext) {
Iterator serviceContecxtes = serviceGroupContext.getServiceContexts();
while (serviceContecxtes.hasNext()) {
ServiceContext serviceContext = (ServiceContext) serviceContecxtes.next();
try {
DependencyManager.destroyServiceObject(serviceContext);
} catch (AxisFault axisFault) {
log.info(axisFault.getMessage());
}
}
}
public void cleanupContexts() {
if (applicationSessionServiceGroupContextTable.size() > 0) {
Iterator applicationScopeSgs =
applicationSessionServiceGroupContextTable.values().iterator();
while (applicationScopeSgs.hasNext()) {
ServiceGroupContext serviceGroupContext =
(ServiceGroupContext) applicationScopeSgs.next();
cleanupServiceContexts(serviceGroupContext);
}
}
if (serviceGroupContextMap.size() > 0) {
Iterator sopaSessionSgs = serviceGroupContextMap.values().iterator();
while (sopaSessionSgs.hasNext()) {
ServiceGroupContext serviceGroupContext =
(ServiceGroupContext) sopaSessionSgs.next();
cleanupServiceContexts(serviceGroupContext);
}
}
}
public String getServiceContextPath() {
String ctxRoot = getContextRoot().trim();
String path = "/";
if (!ctxRoot.equals("/")) {
path = ctxRoot + "/";
}
if (servicePath == null || servicePath.trim().length() == 0) {
throw new IllegalArgumentException("service path cannot be null or empty");
} else {
path += servicePath.trim();
}
return path;
}
public String getRESTContextPath() {
String ctxRoot = getContextRoot().trim();
String path = "/";
if (!ctxRoot.equals("/")) {
path = ctxRoot + "/";
}
if (restPath == null || restPath.trim().length() == 0) {
throw new IllegalArgumentException("service path cannot be null or empty");
} else {
path += restPath.trim();
}
return path;
}
public String getServicePath() {
if (servicePath == null || servicePath.trim().length() == 0) {
throw new IllegalArgumentException("service path cannot be null or empty");
}
return servicePath.trim();
}
public String getRESTPath() {
if (restPath == null || restPath.trim().length() == 0) {
throw new IllegalArgumentException("REST path cannot be null or empty");
}
return restPath.trim();
}
public String getContextRoot() {
if (contextRoot == null || contextRoot.trim().length() == 0) {
throw new IllegalArgumentException("context root cannot be null or empty");
}
return this.contextRoot.trim();
}
public void setServicePath(String servicePath) {
this.servicePath = servicePath;
}
public void setRESTPath(String restPath) {
this.restPath = restPath;
}
public void setContextRoot(String contextRoot) {
this.contextRoot = contextRoot;
}
/**
* This will be used to fetch the serviceGroupContextTimoutInterval from any place available.
*/
public long getServiceGroupContextTimoutInterval() {
Integer serviceGroupContextTimoutIntervalParam =
(Integer) getProperty(Constants.Configuration.CONFIG_CONTEXT_TIMOUT_INTERVAL);
if (serviceGroupContextTimoutIntervalParam != null) {
serviceGroupContextTimoutInterval = serviceGroupContextTimoutIntervalParam.intValue();
}
return serviceGroupContextTimoutInterval;
}
}