All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jp.go.nict.langrid.cosee.AspectBase Maven / Gradle / Ivy

Go to download

Service container including JSON-RPC handler for the Service Grid Server Software and java web services.

There is a newer version: 1.1.3
Show newest version
/*
 * $Id: AspectBase.java 1498 2015-02-13 03:50:47Z t-nakaguchi $
 *
 * This is a program for Language Grid Core Node. This combines multiple language resources and provides composite language services.
 * Copyright (C) 2005-2008 NICT Language Grid Project.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see .
 */
package jp.go.nict.langrid.cosee;

import java.net.URI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.soap.MimeHeaders;

import jp.go.nict.langrid.commons.cs.calltree.CallNode;
import jp.go.nict.langrid.commons.cs.calltree.CallTreeUtil;
import jp.go.nict.langrid.commons.lang.StringUtil;
import jp.go.nict.langrid.commons.rpc.RpcFault;
import jp.go.nict.langrid.commons.rpc.RpcHeader;
import jp.go.nict.langrid.commons.rpc.TransportHeader;
import jp.go.nict.langrid.commons.util.Pair;
import jp.go.nict.langrid.commons.ws.LangridConstants;
import jp.go.nict.langrid.commons.ws.ServiceContext;
import jp.go.nict.langrid.commons.ws.util.MimeHeadersUtil;

/**
 * 
 * 
 * @author $Author: t-nakaguchi $
 * @version $Revision: 1498 $
 */
public class AspectBase{
	/**
	 * 
	 * 
	 */
	public AspectBase(EndpointRewriter[] rewriters){
		this.rewriters = rewriters;
	}

	protected void beginProcess(
			ServiceContext serviceContext, long processId)
	{
//		logger.info("process begin. tid: " + Thread.currentThread().getId()
//				+ "  pid: "+ processId);

		Map props = new HashMap();
		// 
		// 
		MimeHeaders mHeaders = serviceContext.getRequestMimeHeaders();
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_FROMADDRESS);
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_CORENODEURL);
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_CALLNEST);
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_TYPEOFUSE);
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_TYPEOFAPPPROVISION);
		extractHttpHeader(mHeaders, props, LangridConstants.HTTPHEADER_FEDERATEDCALL_BYPASSINGINVOCATION);
		// 呼出アドレスが無ければ足す。
		if(mHeaders.getHeader(LangridConstants.HTTPHEADER_FROMADDRESS) == null){
			props.put(
					LangridConstants.HTTPHEADER_FROMADDRESS
					, serviceContext.getRemoteAddress());
		}
		// SOAPヘッダ情報を抽出
		Iterable rHeaders = serviceContext.getRequestRpcHeaders();
		extractSoapHeader(rHeaders, props, LangridConstants.ACTOR_SERVICE_TREEBINDING);

		// calltree準備
		props.put("calltree", new ArrayList());
		// gridTracks準備
		props.put("gridTracks", new ArrayList>());
		// additionalMimeHeaders準備
		props.put("additionalMimeHeaders", new ArrayList());
		// additionalRpcHeaders準備
		props.put("additionalRpcHeaders", new ArrayList());
		// responseHeaders準備
		props.put("responseHeaders", new ArrayList());

		// 各RewriterのextractPropertiesを呼び出す
		for(EndpointRewriter r : rewriters){
			r.extractProperties(
				serviceContext, props
				);
		}
		idToProperties.put(processId, props);
	}

	protected void initEndpointRewriters(
			ServiceContext serviceContext, long processId, EndpointRewriter[] rewriters){
		for(EndpointRewriter r : rewriters){
			r.extractProperties(
				serviceContext, idToProperties.get(processId)
				);
		}
	}

	protected Endpoint rewriteEndpoint(
			long processId, URI processUri
			, long invocationId, String partnerLinkName
			, URI serviceNamespace, Endpoint original
			){
		return rewriteEndpoint(processId, processUri
				, invocationId, partnerLinkName
				, serviceNamespace, original, rewriters);
	}

	protected Endpoint rewriteEndpoint(
			long processId, URI processUri
			, long invocationId, String partnerLinkName
			, URI serviceNamespace, Endpoint original
			, EndpointRewriter[] rewriters)
	{
		Map properties = idToProperties.get(processId);
		Endpoint ep = original;
		synchronized (properties) {
			if(properties == null){
				logger.severe(
						"[tid: "
						+ Thread.currentThread().getId()
						+ "] properteis for process:"
						+ processId
						+ " is null!! using original endpoint:"
						+ original.getAddress()
						+ " ["
						+ original.getUserName()
						+ ":********]"
						);
				return original;
			}

			for(EndpointRewriter r : rewriters){
				ep = r.rewrite(ep, properties, processUri
						, partnerLinkName, serviceNamespace);
			}
			if(ep.getServiceId() != null){
				properties.put("invocation#" + invocationId, ep.getServiceId());
			} else if(ep.getAddress() != null){
				properties.put("invocation#" + invocationId, ep.getAddress().toString());
			}
		}
		return ep;
	}

	protected void appendInvocationHeaders(
			long processId, long invocationId
			, String partnerLinkName
			, Map mimeHeaders
			, Collection rpcHeaders)
	{
		Map properties = idToProperties.get(processId);
		synchronized (properties) {
			if(properties == null){
				logger.severe("properties is null!");
				return;
			}

			Map tempProperties = new HashMap(
					properties
					);
			for(EndpointRewriter r : rewriters){
				r.adjustProperties(tempProperties, partnerLinkName);
			}

			// HTTPヘッダ情報をコピー
			copyHttpHeader(tempProperties, mimeHeaders, LangridConstants.HTTPHEADER_FROMADDRESS);
			copyHttpHeader(tempProperties, mimeHeaders, LangridConstants.HTTPHEADER_CALLNEST);
			copyHttpHeader(tempProperties, mimeHeaders, LangridConstants.HTTPHEADER_TYPEOFUSE);
			copyHttpHeader(tempProperties, mimeHeaders, LangridConstants.HTTPHEADER_TYPEOFAPPPROVISION);
			copyHttpHeader(tempProperties, mimeHeaders, LangridConstants.HTTPHEADER_FEDERATEDCALL_BYPASSINGINVOCATION);
			copyAdditionalMimeHeaders(tempProperties, mimeHeaders);

			// Rpcヘッダ情報をコピー
			copyRpcHeader(tempProperties, rpcHeaders, LangridConstants.ACTOR_SERVICE_TREEBINDING);
			copyAdditionalRpcHeaders(tempProperties, rpcHeaders);
		}
	}

	/**
	 * 
	 * 
	 */
	@SuppressWarnings("unchecked")
	protected void processInvocationResponseHeaders(
			long processId, long invocationId, String invocationName, long deltaTime
			, MimeHeaders mimeHeaders
			, Iterable rpcHeaders, RpcFault rpcFault)
	{
		Map properties = idToProperties.get(processId);
		if(properties == null){
			logger.severe("properties is null!");
			return;
		}
		Collection nodes = (Collection)properties.get(
				"calltree");
		String serviceId = properties.get("invocation#" + invocationId).toString();
		try{
			CallNode node = CallTreeUtil.createNode(mimeHeaders, rpcHeaders);
			node.setServiceId(serviceId);
			node.setResponseTimeMillis(deltaTime);
			node.setInvocationName(invocationName);
			if(rpcFault != null){
				node.setFaultCode(rpcFault.getFaultCode());
				node.setFaultString(rpcFault.getFaultString());
	//			logger.info("soap fault: " + fault.getFaultCode() + "[" + fault.getFaultString() + "]");
			}
	//		logger.info("receive invocation response.  tid: " + Thread.currentThread().getId()
	//				+ "  pid: " + processId + "  iid: " + invocationId);
			nodes.add(node);
		} catch(ParseException e){
			logger.log(Level.WARNING
					, "failed to add call node for service id \"" +
					serviceId + "\" because of invalid calltree text."
					, e);
		}
		Collection> gridTracks = (Collection>)properties.get("gridTracks");
		gridTracks.add(Pair.create(
				invocationName,
				MimeHeadersUtil.getJoinedValue(mimeHeaders, LangridConstants.HTTPHEADER_GRIDTRACK))
				);
	}

	/**
	 * 
	 * 
	 */
	@SuppressWarnings("unchecked")
	protected void appendResponseHeaders(long processId
			, MimeHeaders mimeHeaders, Collection rpcHeaders){
		Map properties = idToProperties.get(processId);
		if(properties == null){
			logger.severe("properties is null!");
			return;
		}
		Collection nodes = (Collection)properties.get(
				"calltree");
		if(nodes.size() > 0){
			rpcHeaders.add(new RpcHeader(
					LangridConstants.ACTOR_SERVICE_CALLTREE
					, "calltree", CallTreeUtil.encodeTree(nodes)
					));
		}

		Collection> gridTracks = (Collection>)
				properties.get("gridTracks");
		if(gridTracks.size() > 0){
			String v = "(" + StringUtil.join(
					gridTracks.toArray(new Pair[]{}),
					p -> p.getFirst() + ":" + p.getSecond(),
					",") + ")";
			mimeHeaders.addHeader(LangridConstants.HTTPHEADER_GRIDTRACK, v);
		}

		Collection headers = (Collection)properties.get(
				"responseHeaders");
		if(headers.size() > 0){
			for(RpcHeader h : headers){
				rpcHeaders.add(h);
			}
		}
	}

	protected void endProcess(long processId){
//		logger.info("process end. tid: " + Thread.currentThread().getId()
//				+ "  pid: "+ processId);
		idToProperties.remove(processId);
	}

	protected Map getProperties(long processId){
		return idToProperties.get(processId);
	}

	private void extractHttpHeader(
			MimeHeaders headers
			, Map properties
			, String key)
	{
		String[] values = headers.getHeader(key);
		if(values != null && values.length > 0){
			String v = MimeHeadersUtil.getJoinedValue(headers, key);
			if(v != null){
				properties.put(key, v);
			}
		}
	}

	private void extractSoapHeader(
			Iterable rpcHeaders
			, Map properties
			, String namespace)
	{
		List headers = new ArrayList();
		properties.put(namespace, headers);
		for(RpcHeader h : rpcHeaders){
			if(h.getNamespace().equals(namespace))
				headers.add(h.clone());
		}
	}

	private void copyHttpHeader(Map properties
			, Map mimeHeaders
			, String key){
		String value = (String)properties.get(key);
		if(value != null){
			mimeHeaders.put(key, value);
		}
	}

	private void copyAdditionalMimeHeaders(Map properties, Map mimeHeaders){
		@SuppressWarnings("unchecked")
		List additionalHeaders = (List)properties.get("additionalMimeHeaders");
		if(additionalHeaders == null) return;
		for(TransportHeader v : additionalHeaders){
			mimeHeaders.put(v.getName(), v.getValue());
		}
	}

	@SuppressWarnings("unchecked")
	private void copyRpcHeader(Map properties
			, Collection headers
			, String key){
		List hds = (List)properties.get(key);
		if(hds == null) return;
		for(RpcHeader h : hds){
			headers.add(h.clone());
		}
	}

	private void copyAdditionalRpcHeaders(Map properties, Collection rpcHeaders){
		@SuppressWarnings("unchecked")
		List additionalHeaders = (List)properties.get("additionalRpcHeaders");
		if(additionalHeaders == null) return;
		for(RpcHeader v : additionalHeaders){
			rpcHeaders.add(v);
		}
	}

	private EndpointRewriter[] rewriters;
	private Map> idToProperties
		= new ConcurrentHashMap>();
	private static Logger logger = LoggerFactory.create();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy