com.aliyun.odps.Session Maven / Gradle / Ivy
The newest version!
package com.aliyun.odps;
import com.aliyun.odps.data.Record;
import com.aliyun.odps.data.SessionQueryResult;
import com.aliyun.odps.sqa.commandapi.utils.CommandUtil;
import com.aliyun.odps.task.SQLRTTask;
import com.aliyun.odps.utils.CSVRecordParser;
import com.aliyun.odps.utils.StringUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.lang.reflect.Type;
public class Session {
public class SubQueryInfo {
public static final String kNotFoundCode = "NotFound";
public static final String kFailedCode = "Failed";
public static final String kOKCode = "ok";
public int queryId = -1;
public String status = kOKCode;
public String result;
public SubQueryInfo(String status, String result) {
this.status = status;
this.result = result;
}
}
public class SubQueryResult {
TableSchema schema = null;
List warnings = new ArrayList<>();
List records = null;
public void setSchema(TableSchema schema) {
this.schema = schema;
}
public void addWarning(String warning) {
this.warnings.add(warning);
}
public void setRecords(List records) {
this.records = records;
}
public TableSchema getSchema() {
return schema;
}
public List getRecords() {
return records;
}
public List getWarnings() {
return warnings;
}
}
public class SessionItem {
public String owner;
public String sessionId;
public String aliasName;
public String version;
}
private static final String DEFAULT_TASK_NAME = "console_sqlrt_task";
private static final long POLL_INTERVAL = TimeUnit.MILLISECONDS.toMillis(1000);
private static final Long SESSION_TIMEOUT = 60L;
private String taskName = DEFAULT_TASK_NAME;
// attach session reuse token
private String token;
private long tokenExpiredHours = 7 * 24;
public Session(Odps odps, Instance instance) {
this(odps, instance, null, DEFAULT_TASK_NAME);
}
public Session(Odps odps, Instance instance, String sessionName, String taskName) {
this.sessionName = sessionName;
this.instance = instance;
this.startSessionMessage = "";
this.taskName = taskName;
this.odps = odps;
}
private Odps odps;
private String sessionName;
private Instance instance;
private String logView;
private boolean isStarted = false;
private SessionProgress progress = null;
private String startSessionMessage;
private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
public static int OBJECT_STATUS_RUNNING = 2;
public static int OBJECT_STATUS_FAILED = 4;
public static int OBJECT_STATUS_TERMINATED = 5;
public static int OBJECT_STATUS_CANCELLED = 6;
public String getLogView() throws OdpsException {
if (logView == null && odps != null) {
logView = new LogView(odps).generateLogView(instance, 7 * 24 /* by default one week. can be set by config */);
}
return logView;
}
public String getLogView(int version) throws OdpsException {
if (logView == null && odps != null) {
logView = new LogView(odps, version).generateLogView(instance, 7 * 24 /* by default one week. can be set by config */);
}
return logView;
}
public void setLogView(String logView) {
this.logView = logView;
}
public String getStartSessionMessage() {
return startSessionMessage;
}
public class SubQueryResponse {
public Integer status;
public String result;
public String warnings;
public Integer subQueryId;
}
public class SessionProgress {
public Integer totalWorkerCount;
public Integer launchedWorkerCount;
public Integer launchedPercentage;
}
/**
* 返回 odps instance 对象
*
* @return instance
*/
public Instance getInstance() {
return instance;
}
/**
* attach 指定名字的 session
* 此调用会立即返回,不会等待 session 启动完成。 可以手动调用 {@link #waitForStart(long)} 来等待启动。
*
* @param odps
* odps 对象
* @param sessionName
* 指定 session 的名字
* @return session 对象
* @throws OdpsException
*/
public static Session attach(Odps odps, String sessionName) throws OdpsException {
return attach(odps, sessionName, null);
}
/**
* attach 指定名字的 session
* 此调用会立即返回,不会等待 session 启动完成。 可以手动调用 {@link #waitForStart(long)} 来等待启动。
*
* @param odps
* odps 对象
* @param sessionName
* 指定的 session 名字
* @param hints
* 能够影响 SQL 执行的Set 参数
* @return
* @throws OdpsException
*/
public static Session attach(Odps odps, String sessionName, Map hints)
throws OdpsException {
return attach(odps, sessionName, hints, null);
}
/**
* attach 指定名字的 session
*
* @param odps
* odps 对象
* @param sessionName
* 指定的 session 名字
* @param hints
* 能够影响 SQL 执行的Set 参数数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @return
* @throws OdpsException
*/
public static Session attach(Odps odps, String sessionName, Map hints,
Long timeout) throws OdpsException {
return attach(odps, sessionName, hints, timeout, DEFAULT_TASK_NAME);
}
/**
* attach 指定名字的 session
*
* @param odps
* odps 对象
* @param sessionName
* 指定的 session 名字
* @param hints
* 能够影响 SQL 执行的Set 参数数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param taskName
* SqlRtTask的taskName
* @return
* @throws OdpsException
*/
public static Session attach(Odps odps, String sessionName, Map hints,
Long timeout, String taskName) throws OdpsException {
return attach(odps, sessionName, hints, timeout, null, taskName);
}
/**
* attach 指定名字的 session
*
* @param odps
* odps 对象
* @param sessionName
* 指定的 session 名字
* @param hints
* 能够影响 SQL 执行的Set 参数数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param runningCluster
* 运行集群
* @param taskName
* SqlRtTask的taskName
* @return
* @throws OdpsException
*/
public static Session attach(Odps odps, String sessionName, Map hints,
Long timeout, String runningCluster, String taskName) throws OdpsException {
if (StringUtils.isNullOrEmpty(sessionName)) {
throw new IllegalArgumentException("Session name can not be empty.");
}
if (hints == null) {
hints = new HashMap<>();
}
hints.put("odps.sql.session.share.id", sessionName);
try {
return createInternal(odps, null, sessionName, null, null, null, hints, timeout, null, runningCluster, taskName);
} finally {
hints.remove("odps.sql.session.share.id");
}
}
/**
* 创建 session
* 此调用会立即返回,不会等待 session 启动完成。 可以手动调用 {@link #waitForStart(long)} 来等待启动。
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory)
throws OdpsException {
return create(odps, workerCount, workerMemory, null, null, null, null, null);
}
/**
* 创建 session
* 此调用会立即返回,不会等待 session 启动完成。 可以手动调用 {@link #waitForStart(long)} 来等待启动。
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @param sessionName
* 指定 session 名字
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory, String sessionName)
throws OdpsException {
return create(odps, workerCount, workerMemory, sessionName, null, null, null, null);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @param sessionName
* 指定 session 名字
* @param workerSpareSpan
* session 对应 cg service 的服务休息时间, 格式是 startHour-endHour
* 例如 0-12 表示0点到12点 worker 数会降为 0。
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory, String sessionName,
String projectName, String workerSpareSpan,
Map hints, Long timeout) throws OdpsException {
return create(odps, workerCount, workerMemory, sessionName, projectName,
workerSpareSpan, hints,
timeout, null);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @param sessionName
* 指定 session 名字
* @param workerSpareSpan
* session 对应 cg service 的服务休息时间, 格式是 startHour-endHour
* 例如 0-12 表示0点到12点 worker 数会降为 0。
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param priority
* session 优先级
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory, String sessionName,
String projectName, String workerSpareSpan,
Map hints, Long timeout, Integer priority) throws OdpsException {
return create(odps, workerCount, workerMemory, sessionName, projectName, workerSpareSpan, hints, timeout, priority, null);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @param sessionName
* 指定 session 名字
* @param workerSpareSpan
* session 对应 cg service 的服务休息时间, 格式是 startHour-endHour
* 例如 0-12 表示0点到12点 worker 数会降为 0。
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param priority
* session 优先级
* @param runningCluster
* 运行集群
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory, String sessionName,
String projectName, String workerSpareSpan,
Map hints, Long timeout, Integer priority, String runningCluster) throws OdpsException {
return createInternal(odps, projectName, sessionName, workerCount, workerMemory,
workerSpareSpan, hints,
timeout, priority, runningCluster);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param workerCount
* session work 数量(单位:个)
* @param workerMemory
* session work 内存 (单位: MB)
* @param sessionName
* 指定 session 名字
* @param workerSpareSpan
* session 对应 cg service 的服务休息时间, 格式是 startHour-endHour
* 例如 0-12 表示0点到12点 worker 数会降为 0。
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param priority
* session 优先级
* @param runningCluster
* 运行集群
* @param taskName
* SqlRtTask的taskName
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, int workerCount, int workerMemory, String sessionName,
String projectName, String workerSpareSpan,
Map hints, Long timeout, Integer priority, String runningCluster,
String taskName) throws OdpsException {
return createInternal(odps, projectName, sessionName, workerCount, workerMemory,
workerSpareSpan, hints,
timeout, priority, runningCluster, taskName);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, String sessionName, String projectName, Map hints, Long timeout) throws OdpsException {
return create(odps, sessionName, projectName, hints, timeout, null);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param priority
* session 优先级
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, String sessionName, String projectName, Map hints, Long timeout, Integer priority) throws OdpsException {
return create(odps, sessionName, projectName, hints, timeout, priority, null);
}
/**
* 创建 session
*
* @param odps
* odps 对象
* @param hints
* 能够影响 SQL 执行的Set 参数
* @param timeout
* 等待 session 启动的超时时间,单位: 秒
* 其中: null 表示从不等待; 0 表示阻塞等待
* @param priority
* session 优先级
* @param runningCluster
* 运行集群
* @return session 对象
* @throws OdpsException
*/
public static Session create(Odps odps, String sessionName, String projectName, Map hints, Long timeout, Integer priority, String runningCluster) throws OdpsException {
return createInternal(odps, projectName, sessionName, null, null,
null, hints, timeout, priority, runningCluster);
}
/**
* 提交查询
*
* @param sql
* sql 语句
* @return 查询结果
* @throws OdpsException
*/
@Deprecated
public SessionQueryResult run(String sql) throws OdpsException {
return run(sql, null);
}
/**
* 提交查询
*
* @param sql
* sql 语句
* @param hints
* 能够影响 SQL 执行的Set 参数
* @return 查询结果
* @throws OdpsException
*/
@Deprecated
public SessionQueryResult run(String sql, Map hints) throws OdpsException {
JsonObject request = new JsonObject();
request.add("query", new JsonPrimitive(sql));
if (hints == null) {
hints = new HashMap();
}
JsonObject settings = new JsonObject();
for (Map.Entry property : hints.entrySet()) {
settings.addProperty(property.getKey(), property.getValue());
}
request.add("settings", settings);
Instance.SetInformationResult setInformationResult = instance.setInformation(taskName, "query", gson.toJson(request));
SubQueryInfo subQueryInfo = null;
if (!setInformationResult.status.equals(SubQueryInfo.kOKCode)) {
// instance not found or failed
subQueryInfo = new SubQueryInfo(setInformationResult.status, setInformationResult.result);
} else if (!StringUtils.isNullOrEmpty(setInformationResult.result)) {
Type type = new TypeToken() {
}.getType();
try {
subQueryInfo = gson.fromJson(setInformationResult.result, type);
} catch (Exception e) {
throw new OdpsException(setInformationResult.result);
}
subQueryInfo.status = setInformationResult.status;
} else {
// there will be no 'result' in response from old sqlrt task
}
return new SessionQueryResult(subQueryInfo, new ListIterator() {
boolean queryTerminated = false;
@Override
protected List list() {
try {
if (queryTerminated) {
return null;
}
while (true) {
SubQueryResponse response = getResponse(instance.getTaskInfo(taskName, "result"));
if (response == null || response.status == null) {
checkTaskStatus();
} else {
if (response.status != OBJECT_STATUS_RUNNING) {
queryTerminated = true;
}
return Arrays.asList(response);
}
}
} catch (OdpsException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
});
}
/**
* 提交查询
*
* @param sql
* sql 语句
* @param hints
* 能够影响 SQL 执行的Set 参数
* @return SubQueryInfo query标识
* @throws OdpsException
*/
public SubQueryInfo runSubQuery(String sql, Map hints) throws OdpsException {
JsonObject request = new JsonObject();
request.add("query", new JsonPrimitive(sql));
if (hints == null) {
hints = new HashMap();
}
JsonObject settings = new JsonObject();
for (Map.Entry property : hints.entrySet()) {
settings.addProperty(property.getKey(), property.getValue());
}
request.add("settings", settings);
Instance.SetInformationResult setInformationResult = instance.setInformation(taskName, "query", gson.toJson(request));
SubQueryInfo subQueryInfo = null;
if (!setInformationResult.status.equals(SubQueryInfo.kOKCode)) {
// instance not found or failed
subQueryInfo = new SubQueryInfo(setInformationResult.status, setInformationResult.result);
} else if (!StringUtils.isNullOrEmpty(setInformationResult.result)) {
Type type = new TypeToken() {}.getType();
try {
subQueryInfo = gson.fromJson(setInformationResult.result, type);
} catch (Exception e) {
throw new OdpsException(setInformationResult.result);
}
subQueryInfo.status = setInformationResult.status;
} else {
throw new OdpsException("Invalid setInformation response.");
}
return subQueryInfo;
}
/**
* 等待SubQuery执行结束获取查询结果
*
* @param queryId
*
* @return 查询结果
* @throws OdpsException
*/
public SubQueryResponse waitForSubqueryTerminated(int queryId) throws OdpsException {
boolean terminated = false;
SubQueryResponse response = new SubQueryResponse();
while (!terminated) {
response = getResponse(instance.getTaskInfo(taskName, "get_finished_status_" + queryId));
if (response == null || response.status == null) {
checkTaskStatus();
} else if (response.status == OBJECT_STATUS_FAILED && response.result.contains("SubQuery not found")) {
throw new OdpsException(response.result);
} else if (response.status != OBJECT_STATUS_RUNNING) {
terminated = true;
}
}
return response;
}
/**
* getInformation查询SubQuery结果. 仅支持select query
*
* @param queryId
* sql 语句
* @return 查询结果
* @throws OdpsException
*/
public SubQueryResult getSubQueryResult(int queryId) throws OdpsException {
String resultString = getSubQueryResultInternal(queryId);
SubQueryResult result = new SubQueryResult();
CSVRecordParser.ParseResult parseResult = CSVRecordParser.parse(resultString);
result.setSchema(parseResult.getSchema());
result.setRecords(parseResult.getRecords());
return result;
}
/**
* getInformation查询SubQuery的原始结果. 主要是用于non-select query,但是这类query是具备result的
*
* @param queryId
* @return
* @throws OdpsException
*/
public SubQueryResult getRawSubQueryResult(int queryId) throws OdpsException {
String resultString = getSubQueryResultInternal(queryId);
SubQueryResult result = new SubQueryResult();
List records = CommandUtil.toRecord(resultString, "Info");
TableSchema schema = new TableSchema();
schema.setColumns(Arrays.asList(records.get(0).getColumns()));
result.setSchema(schema);
result.setRecords(records);
return result;
}
/**
* 从odps_worker查询SubQuery结果
*
* @param queryId
* sql 语句
* @return 查询结果
* @throws OdpsException
*/
public SubQueryResult getSubQueryResultFromWorker(int queryId) throws OdpsException {
SubQueryResponse response = waitForSubqueryTerminated(queryId);
String subqueryId = "session_query_" + queryId;
String resultString = instance.getRawSubqueryResults(subqueryId, taskName);
if (response.status == OBJECT_STATUS_FAILED) {
throw new OdpsException(resultString);
} else {
if (!StringUtils.isNullOrEmpty(response.result)) {
resultString += response.result;
}
SubQueryResult result = new SubQueryResult();
if (!StringUtils.isNullOrEmpty(response.warnings)) {
result.addWarning(response.warnings);
}
CSVRecordParser.ParseResult parseResult = CSVRecordParser.parse(resultString);
result.setSchema(parseResult.getSchema());
result.setRecords(parseResult.getRecords());
return result;
}
}
/**
* 查询当前CacheOn的变量列表
*
* @param
* @return 查询结果
* @throws OdpsException
*/
public List showVariables(Map hints) throws OdpsException {
SubQueryInfo subQueryInfo = runSubQuery("show variables;", hints);
String resultString = getSubQueryResultInternal(subQueryInfo.queryId);
List vars = new ArrayList<>();
if (!StringUtils.isNullOrEmpty(resultString)) {
vars = Arrays.asList(resultString.split("\n"));
}
return vars;
}
private String getSubQueryResultInternal(int queryId) throws OdpsException {
SubQueryResult result = new SubQueryResult();
String resultString = "";
boolean terminated = false;
while(!terminated) {
SubQueryResponse response = getResponse(instance.getTaskInfo(taskName, "result_" + queryId));
if (response == null || response.status == null) {
checkTaskStatus();
} else {
if (!StringUtils.isNullOrEmpty(response.result)) {
resultString += response.result;
}
if (!StringUtils.isNullOrEmpty(response.warnings)) {
result.addWarning(response.warnings);
}
if (response.status == OBJECT_STATUS_FAILED) {
throw new OdpsException(resultString);
} else if (response.status != OBJECT_STATUS_RUNNING) {
terminated = true;
}
}
}
return resultString;
}
/**
* 停止 session
*
* @throws OdpsException
*/
public void stop() throws OdpsException {
instance.stop();
}
/**
* 阻塞等待 session 启动
*
* @throws OdpsException
*/
public void waitForStart() throws OdpsException {
waitForStart(0L);
}
/**
* 判断 session 是否已经成功启动
*
* @return 是否已经启动
* @throws OdpsException 启动异常
*/
public boolean isStarted() throws OdpsException {
if (!isStarted) {
SubQueryResponse response = getResponse(instance.getTaskInfo(taskName, "status"));
if (response == null || response.status == null) {
checkTaskStatus();
} else if (response.status == OBJECT_STATUS_RUNNING) {
isStarted = true;
if (response.result != null && response.result.length() > 0) {
startSessionMessage += response.result;
}
} else if (response.status == OBJECT_STATUS_FAILED) {
throw new OdpsException(
String.format("Start session[%s] failed: %s ", instance.getId(), response.result));
} else if(!StringUtils.isNullOrEmpty(response.result)) {
try {
progress = gson.fromJson(response.result, SessionProgress.class);
} catch (Exception e) {
// ignore
}
}
}
return isStarted;
}
/**
* 等待 attach session 返回
*
* @param timeout
* 等待的超时时间(单位: 秒)
* 0 表示阻塞等待
* @throws OdpsException
*/
public void waitAttachSuccess(long timeout) throws OdpsException {
long startTime = System.currentTimeMillis();
long endTime = 0;
if (timeout > 0) {
endTime += startTime + TimeUnit.SECONDS.toMillis(timeout);
}
while (0 == endTime || System.currentTimeMillis() < endTime) {
SubQueryResponse response = getResponse(instance.getTaskInfo(taskName, "wait_attach_success"));
if (response == null || response.status == null) {
checkTaskStatus();
} else if (response.status == OBJECT_STATUS_RUNNING) {
if (response.result != null && response.result.length() > 0) {
startSessionMessage += response.result;
}
return;
} else if (response.status == OBJECT_STATUS_FAILED || response.status == OBJECT_STATUS_TERMINATED) {
throw new OdpsException(
String.format("Attach session[%s] failed: %s ", instance.getId(), response.result));
}
}
instance.stop();
throw new OdpsException(String.format("Attach session[%s] timeout.", instance.getId()));
}
/**
* 返回当前 attach session 可复用的 token
*
* @return token
*/
public String getToken() throws OdpsException {
if (token == null && odps != null) {
token = new LogView(odps).generateInstanceToken(instance, tokenExpiredHours);
}
return token;
}
/**
* get sqlstats of subqyery
*
* @return stats
* @throws OdpsException 启动异常
*/
public String getQueryStats() throws OdpsException {
return getInformation("sqlstats");
}
/**
* get sqlstats of subqyery
* @param queryId
* queryId
* @return stats
* @throws OdpsException 启动异常
*/
public String getQueryStats(int queryId) throws OdpsException {
return getInformation("sqlstats_" + String.valueOf(queryId));
}
/**
* getInformation
*
* @return stats
* @throws OdpsException 获取information异常
*/
public String getInformation(String key) throws OdpsException {
SubQueryResponse response = getResponse(instance.getTaskInfo(taskName, key));
if (response != null && response.result != null) {
return response.result;
}
return null;
}
/**
* setInformation
*
* @return stats
* @throws OdpsException 设置information异常
*/
public String setInformation(String key, String value) throws OdpsException {
String result = instance.setTaskInfo(taskName, key, value);
return result;
}
/**
* 获取 session 启动的进度
* @return session 启动的当前进度,包含 worker 启动数和启动总数,启动进度百分比
*
* @throws OdpsException
*/
public SessionProgress getStartProgress() throws OdpsException {
if (progress == null) {
isStarted();
}
return progress;
}
/**
* 等待 session 启动
*
* @param timeout
* 等待的超时时间(单位: 秒)
* 0 表示阻塞等待
* @throws OdpsException
*/
public void waitForStart(long timeout) throws OdpsException {
long startTime = System.currentTimeMillis();
long endTime = 0;
if (timeout > 0) {
endTime += startTime + TimeUnit.SECONDS.toMillis(timeout);
}
while (0 == endTime || System.currentTimeMillis() < endTime) {
if (isStarted()) {
return;
}
sleep();
}
throw new OdpsException("Start session[%s] timeout.", instance.getId());
}
private SubQueryResponse getResponse(String result) throws OdpsException {
if (StringUtils.isNullOrEmpty(result)) {
return null;
}
try {
return gson.fromJson(result, SubQueryResponse.class);
} catch (Exception e) {
throw new OdpsException("Invalid response:" + result);
}
}
private void checkTaskStatus() throws OdpsException {
Instance.TaskStatus status = instance.getTaskStatus().get(taskName);
if (status != null && status.getStatus() != Instance.TaskStatus.Status.RUNNING) {
throw new OdpsException(String.format("Session[%s] is %s: %s", instance.getId(),
status.getStatus().toString(),
instance.getTaskResults().get(taskName)));
}
}
private static Session createInternal(Odps odps, String projectName, String sessionName,
Integer workerCount, Integer workerMemory,
String workerSpareSpan, Map hints,
Long timeout, Integer priority, String runningCluster) throws OdpsException {
return createInternal(odps, projectName, sessionName, workerCount, workerMemory,
workerSpareSpan, hints, timeout, priority, runningCluster, DEFAULT_TASK_NAME);
}
private static Session createInternal(Odps odps, String projectName, String sessionName,
Integer workerCount, Integer workerMemory,
String workerSpareSpan, Map hints,
Long timeout, Integer priority, String runningCluster,
String taskName) throws OdpsException {
if (projectName != null && projectName.trim().isEmpty()) {
throw new IllegalArgumentException("Project name can not be empty.");
}
if (null == hints) {
hints = new HashMap();
}
projectName = (projectName == null ? odps.getDefaultProject() : projectName);
if (!StringUtils.isNullOrEmpty(workerSpareSpan)) {
hints.put("odps.sql.session.worker.sparespan", workerSpareSpan);
}
if (!StringUtils.isNullOrEmpty(sessionName)) {
hints.put("odps.sql.session.name", sessionName.trim());
}
if (null != workerCount) {
hints.put("odps.sql.session.worker.count", workerCount.toString());
}
if (null != workerMemory) {
hints.put("odps.sql.session.worker.memory", workerMemory.toString());
}
String userSubmitMode = hints.get("odps.sql.submit.mode");
hints.put("odps.sql.submit.mode", "script");
SQLRTTask task = new SQLRTTask();
task.setName(taskName);
try {
String json = gson.toJson(hints);
task.setProperty("settings", json);
} catch (Exception e) {
throw new OdpsException(e.getMessage(), e);
}
if (userSubmitMode == null || userSubmitMode.isEmpty()) {
hints.remove("odps.sql.submit.mode");
} else {
hints.put("odps.sql.submit.mode", userSubmitMode);
}
Instance instance = odps.instances().create(projectName, task, priority, runningCluster);
Session session = new Session(odps, instance, sessionName, taskName);
// attach mode, long polling
if (hints.containsKey("odps.sql.session.share.id")) {
if (timeout != null) {
session.waitAttachSuccess(timeout);
} else {
session.waitAttachSuccess(SESSION_TIMEOUT);
}
} else {
if (timeout != null) {
session.waitForStart(timeout);
}
}
return session;
}
public void printLogView() throws OdpsException{
System.out.println("");
System.err.println("ID = " + instance.getId());
System.err.println("Log view:");
System.err.println(getLogView());
}
public void cancelQuery(int queryId) throws OdpsException {
Instance.SetInformationResult setInformationResult
= instance.setInformation(taskName, "cancel", String.valueOf(queryId));
if (!setInformationResult.status.equals(SubQueryInfo.kOKCode)) {
throw new OdpsException(setInformationResult.result);
}
}
private void sleep() throws OdpsException {
try {
Thread.sleep(POLL_INTERVAL);
} catch (InterruptedException e) {
throw new OdpsException("Interrupted while sleep.", e);
}
}
public String getSessionName() {
return sessionName;
}
public String getTaskName() { return taskName; }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy