com.logicbus.backend.Context Maven / Gradle / Ivy
package com.logicbus.backend;
import java.io.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import com.alogic.xscript.LogicletContext;
import com.anysoft.formula.DataProvider;
import com.anysoft.util.DefaultProperties;
import com.logicbus.backend.message.Message;
/**
* 服务访问的上下文
*
*
* 记录了本次访问的一些上下文信息,例如服务参数、客户端IP等
*
* @author duanyy
*
* @version 1.0.5 [20140412 duanyy]
* - 改进消息传递模型
*
* @version 1.0.7 [20140418 duanyy]
* - 增加生成全局序列号功能
*
* @version 1.4.0 [20141117 duanyy]
* - 将MessageDoc和Context进行合并整合
* - 实现了DataProvider
*
* @version 1.6.2.1 [20141218 duanyy]
* - 增加对Comet技术的支持
*
* @version 1.6.3.10 [20140324 duanyy]
* - 增加忽略本次输出的功能
*
* @version 1.6.3.30 [20150714 duanyy]
* - 全局序列号只包含数字和字母
*
* @version 1.6.5.6 [20160523 duanyy]
* - 不再从MessageDoc上继承
* - 增加报文长度
* - 增加全局调用次序
*
* @version 1.6.5.24 [20160718 duanyy]
* - 增加getPathInfo方法
*
* @version 1.6.7.1 [20170117 duanyy]
* - trace日志调用链中的调用次序采用xx.xx.xx.xx字符串模式
*
* @version 1.6.7.4 [20170118 duanyy]
* - 服务耗时单位改为ns
*
* @version 1.6.7.15 [20170221 duanyy]
* - 增加设置Content-Length接口
*
* @version 1.6.9.8 [20170821 duanyy]
* - 服务上下文增加keyword关键字,和tlog对接;
*
* @version 1.6.10.9 [20171124 duanyy]
* - 规范化URL和URI的取值
*
* @version 1.6.11.45 [duanyy 20180722]
* - 增加getHostDomain方法
*
* @version 1.6.11.59 [20180911 duanyy]
* - 增加基于Context的LogicletContext实现;
*
* @version 1.6.12.29 [20190409]
* - 优化底层的错误代码的处理;
*
* @version 1.6.14.6 [20210415 duanyy]
* - 增加baseUrl的获取方法
*/
public abstract class Context extends DefaultProperties implements DataProvider{
public static final String DFT_CODE = "core.ok";
public static final int DFT_STATUS = 200;
public static final String DFT_REASON = "ok";
public static final String DFT_KEYWORD = "";
public static final int BUF_SIZE = 1024;
/**
* 文档编码
*/
protected String encoding = "utf-8";
/**
* 状态码
*/
protected int status = DFT_STATUS;
/**
* 结果代码
*/
protected String returnCode = DFT_CODE;
/**
* 原因
*/
protected String reason = DFT_REASON;
/**
* 业务关键字
*/
protected String keyword = DFT_KEYWORD;
/**
* 时间戳
*/
protected long timestamp = System.currentTimeMillis();
/**
* the start time
*/
private long m_start_time;
/**
* the end time
*/
private long m_end_time;
/**
* 消息实例
*/
protected Message msg = null;
/**
* 是否允许cache
*/
protected boolean enableClientCache = false;
/**
* 构造上下文
*
* @param _encoding
*/
protected Context(String _encoding){
encoding = _encoding;
}
/**
* 获取文档编码
* @return 编码
*/
public String getEncoding(){return encoding;}
public long getTimestamp(){return timestamp;}
/**
* to get the start time
* @return start time
*/
public long getStartTime(){return m_start_time;}
/**
* to set the start time
* @param start_time start time
*/
public void setStartTime(long start_time){m_start_time = start_time;}
/**
* to get the end time
* @return end time
*/
public long getEndTime(){return m_end_time;}
/**
* to set the end time
* @param end_time end time
*/
public void setEndTime(long end_time){m_end_time = end_time;}
/**
* 获取结果代码
* @return 结果代码
*/
public String getReturnCode(){return returnCode;}
/**
* 获取原因
* @return 原因
*/
public String getReason(){return reason;}
/**
* 获取业务关键字
* @return 业务关键字
*/
public String getKeyword(){return keyword;}
public int getStatus(){return status;}
/**
* 获取时长
* @return 时长
*/
public long getDuration(){return m_end_time - m_start_time;}
/**
* 设置调用结果
*
* @param _code 结果代码
* @param _reason 原因
*/
public void setReturn(int status,String _code,String _reason){
this.status = status;
returnCode = _code;
reason = _reason;
}
public void setStatus(int status){
this.status = status;
}
public void setKeyword(String keyword){
this.keyword = keyword;
}
public void enableClientCache(boolean enable){
this.enableClientCache = enable;
}
public boolean enableClientCache(){
return this.enableClientCache;
}
/**
* 作为消息处理
*
* @param clazz Message实现类
* @throws ServantException 当创建Message实例发生异常的时候,抛出异常代码为:core.instance_create_error
*/
public Message asMessage(Class clazz){
if (msg != null)
return msg;
try {
msg = (Message)clazz.getDeclaredConstructor().newInstance();
msg.init(this);
} catch (Exception e) {
logger.info(ExceptionUtils.getStackTrace(e));
throw new ServantException("core.e1002",
"Can not create instance of " + clazz.getName() + ":" + e.getMessage());
}
return msg;
}
@Override
public String toString(){
return msg == null ? null:msg.toString();
}
/**
* 完成服务,写出结果
*/
abstract public void finish();
/**
* to get the client ip
* @return client ip
*/
abstract public String getClientIp();
/**
* to get the client ip
* @return client ip
*/
abstract public String getClientRealIp();
/**
* to get the request path
* @return request path
*/
abstract public String getPathInfo();
/**
* 获取主机信息
* @return 主机信息
*/
abstract public String getHost();
/**
* 获取主机域名
* @return 主机域名
*/
abstract public String getHostDomain();
/**
* 获取请求路径
* @return request路径
*/
abstract public String getRequestURI();
/**
* 获取请求的URL
* @return URL
*/
abstract public String getRequestURL();
abstract public String getUrlBase();
/**
* 获取请求的方法
*
* @return 请求的方法,POST,GET等
*
* @since 1.6.1.1
*/
abstract public String getMethod();
/**
* 获取报文大小
* @return 报文大小
*/
abstract public long getContentLength();
/**
* 获取全局序列号
* @return 全局序列号
*
* @since 1.0.7
*/
abstract public String getGlobalSerial();
/**
* 获取全局序列号的调用次序
* @return 调用次序
*
* @since 1.6.5.6
*/
abstract public String getGlobalSerialOrder();
/**
* 获取请求的Content-Type
*
* @return Content-Type
*/
abstract public String getRequestContentType();
/**
* 获取请求头信息
* @param id 信息ID
* @return 信息值
*/
abstract public String getRequestHeader(String id);
/**
* 设置响应头的信息
* @param id 信息
* @param value 信息值
*/
abstract public void setResponseHeader(String id,String value);
/**
* 设置响应的Content-Type
* @param contentType
*/
abstract public void setResponseContentType(String contentType);
abstract public void setResponseContentLength(int contentLength);
abstract public String getQueryString();
/**
* 获取InputStream
* @return InputStream
* @since 1.6.1.1
*/
abstract public InputStream getInputStream() throws IOException;
/**
* 获取OutputStram
* @return OutputStram
* @since 1.6.1.1
*/
abstract public OutputStream getOutputStream() throws IOException;
/**
* 获取请求的输入数据
*
*
* 如果有必要,MessageDoc将提前截取请求数据,以byte数组的形式放在RequestRaw中。
*
* @return byte[]形式的输入数据
*/
abstract public byte [] getRequestRaw();
@Override
public String getValue(String varName, Object context, String defaultValue) {
return GetValue(varName, defaultValue);
}
@Override
public Object getContext(String varName) {
return this;
}
/**
* 从输入流中读入文本
* @param _in 输入流
* @param _encoding 编码
* @return 文本
*/
public static String readFromInputStream(InputStream _in,String _encoding) throws IOException{
byte[] data = readBytesFromInputStream(_in);
return new String(data,_encoding);
}
/**
* 从输入流中读取字节
* @param in 输入流
* @return 字节数组
* @throws IOException
*/
public static byte [] readBytesFromInputStream(InputStream in) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream(BUF_SIZE*4);
byte[] buf =new byte[BUF_SIZE];
int size=0;
while((size=in.read(buf))!=-1)
{
bos.write(buf,0,size);
}
return bos.toByteArray();
}
/**
* 向输出流输出文本
*
* @param out 输出流
* @param doc 输出文档
* @param encoding 编码
*/
public static void writeToOutpuStream(OutputStream out,String doc,String encoding) throws IOException{
out.write(doc.getBytes(encoding));
}
public static void writeToOutpuStream(OutputStream out,byte[] bytes) throws IOException{
out.write(bytes);
}
public static class ServantLogicletContext extends LogicletContext {
/**
* 客户端ip
*/
public static final String CLIENTIP = "$clientIp";
/**
* 真实的客户端ip
*/
public static final String CLIENTIPREAL = "$clientIpReal";
/**
* 本次服务的全局序列号
*/
public static final String SN = "$sn";
/**
* 主机信息
*/
public static final String HOST = "$host";
/**
* 主机域名
*/
public static final String HOST_DOMAIN = "$hostdomain";
/**
* 请求方法
*/
public static final String METHOD = "$method";
/**
* 请求参数
*/
public static final String QUERY = "$query";
/**
* 请求完整的URI
*/
public static final String URI = "$uri";
/**
* 请求完整的URL
*/
public static final String URL = "$url";
public static final String BASE_URL = "$baseUrl";
/**
* 请求的路径
*/
public static final String PATH = "$path";
protected Context context = null;
public ServantLogicletContext(Context ctx) {
super(ctx);
context = ctx;
}
@Override
protected String _GetValue(String name) {
if (context != null){
switch(name){
case CLIENTIP:
return context.getClientIp();
case CLIENTIPREAL:
return context.getClientRealIp();
case SN:
return context.getGlobalSerial();
case HOST:
return context.getHost();
case METHOD:
return context.getMethod();
case QUERY:
return context.getQueryString();
case URI:
return context.getRequestURI();
case PATH:
return context.getPathInfo();
case URL:
return context.getRequestURL();
case BASE_URL:
return context.getUrlBase();
case HOST_DOMAIN:
return context.getHostDomain();
}
}
return super._GetValue(name);
}
}
}