Commit 3e829a3a authored by liqin's avatar liqin 💬

bug fixed

parent a8fb71d7
......@@ -102,6 +102,7 @@ public class Constants {
// Executors can use cpu load calculated from this period to take/skip polling turns
public static final int DEFAULT_AZKABAN_POLLING_CRITERIA_CPU_LOAD_PERIOD_SEC = 60;
public static class ConfigurationKeys {
// Configures Azkaban to use new polling model for dispatching
......
/*
* Copyright 2017 LinkedIn Corp.
*
* 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.
*/
dependencies {
compile project(':az-core')
compile project(':azkaban-spi')
......
......@@ -38,6 +38,7 @@ public class AlerterHolder {
@Inject
public AlerterHolder(final Props props, final Emailer mailAlerter) {
logger.info("job配置=========》"+props.toString());
try {
this.alerters = loadAlerters(props, mailAlerter);
} catch (final Exception ex) {
......@@ -47,12 +48,12 @@ public class AlerterHolder {
}
private Map<String, Alerter> loadAlerters(final Props props, final Emailer mailAlerter) {
logger.info("================load报警器=================");
final Map<String, Alerter> allAlerters = new HashMap<>();
// load built-in alerters
allAlerters.put("email", mailAlerter);
// load external alerters
//添加手机警报器
allAlerters.put("sms", new SmsAlerter(props));
// load all plugin alerters
final String pluginDir = props.getString("alerter.plugin.dir", "plugins/alerter");
allAlerters.putAll(loadPluginAlerters(pluginDir));
......
......@@ -122,6 +122,12 @@ public class ExecutableFlow extends ExecutableFlowBase {
if (flow.getFailureEmails() != null) {
this.executionOptions.setFailureEmails(flow.getFailureEmails());
}
if (flow.getSuccessSms() != null) {
this.executionOptions.setSuccessSms(flow.getSuccessSms());
}
if (flow.getFailureSms() != null) {
this.executionOptions.setFailureSms(flow.getFailureSms());
}
}
@Override
......
......@@ -59,7 +59,7 @@ public class ExecutionController extends EventHandler implements ExecutorManager
private final AlerterHolder alerterHolder;
private final ExecutorHealthChecker executorHealthChecker;
private final int maxConcurrentRunsOneFlow;
private final Map<Pair<String, String>, Integer> maxConcurrentRunsPerFlowMap;
private final Map<Pair<String,String>, Integer> maxConcurrentRunsPerFlowMap;
private final CommonMetrics commonMetrics;
private final Props azkProps;
......
......@@ -18,8 +18,13 @@ package azkaban.executor;
import javax.annotation.Nullable;
import javax.inject.Inject;
import azkaban.utils.FileIOUtils;
import org.apache.log4j.Logger;
import java.util.Arrays;
import java.util.List;
/**
* Handles removing of running executions (after they have been deemed to be be done or orphaned).
*/
......@@ -94,9 +99,21 @@ public class ExecutionFinalizer {
this.updaterStage.set("finalizing flow " + execId + " alerting and emailing");
if (alertUser) {
String[] finalizeFlowReasons = ExecutionControllerUtils.getFinalizeFlowReasons(reason,
originalError);
try {
List<String> errorLogs = ExecutionControllerUtils.getErrorLogs(flow, executorLoader);
for (String finalizeFlowReason : finalizeFlowReasons) {
String erroLine = ExecutionControllerUtils.getErroLine(finalizeFlowReason);
errorLogs.add(erroLine);
}
finalizeFlowReasons = errorLogs.toArray(new String[errorLogs.size()]);
}catch (Exception e){
e.printStackTrace();
}
ExecutionControllerUtils.alertUserOnFlowFinished(flow, this.alerterHolder,
ExecutionControllerUtils.getFinalizeFlowReasons(reason,
originalError));
finalizeFlowReasons, this.executorLoader);
}
}
......
......@@ -58,9 +58,8 @@ import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
/**
/**执行管理器用于管理客户端工作。
* Executor manager used to manage the client side job.
*
* @deprecated replaced by {@link ExecutionController}
*/
@Singleton
......@@ -81,7 +80,7 @@ public class ExecutorManager extends EventHandler implements
private final RunningExecutionsUpdaterThread updaterThread;
private final ExecutorApiGateway apiGateway;
private final int maxConcurrentRunsOneFlow;
private final Map<Pair<String, String>, Integer> maxConcurrentRunsPerFlowMap;
private final Map<Pair<String,String>, Integer> maxConcurrentRunsPerFlowMap;
private final ExecutorManagerUpdaterStage updaterStage;
private final ExecutionFinalizer executionFinalizer;
private final ActiveExecutors activeExecutors;
......@@ -892,6 +891,8 @@ public class ExecutorManager extends EventHandler implements
final String exFlowKey = exflow.getProjectName() + "." + exflow.getId() + ".submitFlow";
// using project and flow name to prevent race condition when same flow is submitted by API and schedule at the same time
// causing two same flow submission entering this piece.
//当API和schedule同时提交相同的流时,使用项目和流名称防止竞态条件
//导致两个相同的流提交进入此部分。
synchronized (exFlowKey.intern()) {
final String flowId = exflow.getFlowId();
......@@ -913,6 +914,7 @@ public class ExecutorManager extends EventHandler implements
exflow.setSubmitTime(System.currentTimeMillis());
// Get collection of running flows given a project and a specific flow name
//获取给定项目和特定流名称的运行流的集合
final List<Integer> running = getRunningFlows(projectId, flowId);
ExecutionOptions options = exflow.getExecutionOptions();
......@@ -965,10 +967,14 @@ public class ExecutorManager extends EventHandler implements
// The exflow id is set by the loader. So it's unavailable until after
// this call.
// exflow id由加载程序设置。所以要到之后才能用
//这个调用。
this.executorLoader.uploadExecutableFlow(exflow);
// We create an active flow reference in the datastore. If the upload
// fails, we remove the reference.
//我们在数据存储中创建一个活动流引用。如果上传
//失败,我们删除引用。
final ExecutionReference reference =
new ExecutionReference(exflow.getExecutionId());
......
......@@ -58,7 +58,7 @@ public class QueuedExecutions {
/**
* <pre>
* Helper method to have a single point of insertion in the queued flows
*
*帮助器方法,以便在队列流中具有单点插入
* @param exflow
* flow to be enqueued
* @param ref
......
......@@ -55,12 +55,14 @@ public class CommonJobProperties {
* Comma delimited list of email addresses for success messages
*/
public static final String SUCCESS_EMAILS = "success.emails";
public static final String NOTIFY_SMS = "notify.sms";
/**
*
* Comma delimited list of email addresses for failure messages
*/
public static final String FAILURE_EMAILS = "failure.emails";
public static final String SUCCESS_SMS = "success.sms";
public static final String FAILURE_SMS = "failure.sms";
/*
* The following are the common props that will be added to the job by azkaban
*/
......
......@@ -42,6 +42,9 @@ public class Flow {
private int numLevels = -1;
private List<String> failureEmail = new ArrayList<>();
private List<String> successEmail = new ArrayList<>();
//添加手机号
private List<String> failureSms=new ArrayList<>();
private List<String> successSms=new ArrayList<>();
private String mailCreator = DefaultMailCreator.DEFAULT_MAIL_CREATOR;
private ArrayList<String> errors;
private int version = -1;
......@@ -119,6 +122,8 @@ public class Flow {
flow.failureEmail = (List<String>) flowObject.get("failure.email");
flow.successEmail = (List<String>) flowObject.get("success.email");
flow.failureSms=(List<String>)flowObject.get("failure.sms");
flow.successSms=(List<String>)flowObject.get("success.sms");
if (flowObject.containsKey("mailCreator")) {
flow.mailCreator = flowObject.get("mailCreator").toString();
}
......@@ -219,7 +224,9 @@ public class Flow {
public List<String> getSuccessEmails() {
return this.successEmail;
}
public List<String> getSuccessSms() {
return this.successSms;
}
public String getMailCreator() {
return this.mailCreator;
}
......@@ -231,7 +238,9 @@ public class Flow {
public List<String> getFailureEmails() {
return this.failureEmail;
}
public List<String> getFailureSms() {
return this.failureSms;
}
public void addSuccessEmails(final Collection<String> emails) {
this.successEmail.addAll(emails);
}
......@@ -239,6 +248,12 @@ public class Flow {
public void addFailureEmails(final Collection<String> emails) {
this.failureEmail.addAll(emails);
}
public void addFailureSms(final Collection<String> sms) {
this.failureSms.addAll(sms);
}
public void addSuccessSms(final Collection<String> sms) {
this.successSms.addAll(sms);
}
public int getNumLevels() {
return this.numLevels;
......@@ -348,6 +363,8 @@ public class Flow {
flowObj.put("edges", objectizeEdges());
flowObj.put("failure.email", this.failureEmail);
flowObj.put("success.email", this.successEmail);
flowObj.put("failure.sms", this.failureSms);
flowObj.put("success.sms", this.successSms);
flowObj.put("mailCreator", this.mailCreator);
flowObj.put("layedout", this.isLayedOut);
flowObj.put("embeddedFlow", this.isEmbeddedFlow);
......
......@@ -67,6 +67,7 @@ public class FlowUtils {
/**
* Change job status to disabled in exflow if the job is in disabledJobs
* 如果作业处于disabledJobs中,则在exflow中将作业状态更改为disabled
*/
public static void applyDisabledJobs(final List<DisabledJob> disabledJobs,
final ExecutableFlowBase exflow) {
......
......@@ -324,6 +324,7 @@ public class DirectoryFlowLoader implements FlowLoader {
final Props jobProp = this.jobPropsMap.get(base.getId());
FlowLoaderUtils.addEmailPropsToFlow(flow, jobProp);
FlowLoaderUtils.addSmsPropsToFlow(flow, jobProp);
flow.addAllFlowProperties(this.flowPropsList);
final Set<String> visitedNodesOnPath = new HashSet<>();
......
......@@ -151,6 +151,7 @@ public class DirectoryYamlFlowLoader implements FlowLoader {
flow.setAzkabanFlowVersion(Constants.AZKABAN_FLOW_VERSION_2_0);
final Props props = azkabanFlow.getProps();
FlowLoaderUtils.addEmailPropsToFlow(flow, props);
FlowLoaderUtils.addSmsPropsToFlow(flow,props);
props.setSource(flowFile.getName());
flow.addAllFlowProperties(ImmutableList.of(new FlowProps(props)));
......
......@@ -225,6 +225,35 @@ public class FlowLoaderUtils {
flow.addSuccessEmails(successEmail);
}
public static void addSmsPropsToFlow(final Flow flow, final Props prop) {
final List<String> successSmsList =
prop.getStringList(CommonJobProperties.SUCCESS_SMS,
Collections.EMPTY_LIST);
final Set<String> successSms = new HashSet<>();
for (final String sms : successSmsList) {
successSms.add(sms.toLowerCase());
}
final List<String> failureSmsList =
prop.getStringList(CommonJobProperties.FAILURE_SMS,
Collections.EMPTY_LIST);
final Set<String> failureSms = new HashSet<>();
for (final String sms : failureSmsList) {
failureSms.add(sms.toLowerCase());
}
final List<String> notifySmslList =
prop.getStringList(CommonJobProperties.NOTIFY_SMS,
Collections.EMPTY_LIST);
for (String sms : notifySmslList) {
sms = sms.toLowerCase();
successSms.add(sms);
failureSms.add(sms);
}
flow.addFailureSms(failureSms);
flow.addSuccessSms(successSms);
}
/**
* Generate flow loader report validation report.
*
......
......@@ -37,8 +37,10 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
public class HttpRequestUtils {
private static final Logger logger = Logger.getLogger(HttpRequestUtils.class);
public static ExecutionOptions parseFlowOptions(final HttpServletRequest req)
throws ServletException {
......@@ -78,6 +80,37 @@ public class HttpRequestUtils {
execOptions.setSuccessEmails(Arrays.asList(emailSplit));
}
}
logger.info("============收到HTTP请求=================");
//添加短信解析
if (hasParam(req, "failureSmsOverride")) {
logger.info("============收到failureSmsOverride=================");
final boolean override = getBooleanParam(req, "failureSmsOverride", false);
execOptions.setFailureSmsOverride(override);
}
if (hasParam(req, "successSmsOverride")) {
logger.info("============successSmsOverride=================");
final boolean override = getBooleanParam(req, "successSmsOverride", false);
execOptions.setSuccessSmsOverride(override);
}
if (hasParam(req, "failureSms")) {
final String emails = getParam(req, "failureSms");
logger.info("============failureSms================="+emails);
if (!emails.isEmpty()) {
final String[] emailSplit = emails.split("\\s*,\\s*|\\s*;\\s*|\\s+");
execOptions.setFailureSms(Arrays.asList(emailSplit));
}
}
if (hasParam(req, "successSms")) {
final String emails = getParam(req, "successSms");
logger.info("============successSms================="+emails);
if (!emails.isEmpty()) {
final String[] emailSplit = emails.split("\\s*,\\s*|\\s*;\\s*|\\s+");
execOptions.setSuccessSms(Arrays.asList(emailSplit));
}
}
if (hasParam(req, "notifyFailureFirst")) {
execOptions.setNotifyOnFirstFailure(Boolean.parseBoolean(getParam(req,
"notifyFailureFirst")));
......@@ -86,6 +119,17 @@ public class HttpRequestUtils {
execOptions.setNotifyOnLastFailure(Boolean.parseBoolean(getParam(req,
"notifyFailureLast")));
}
if(hasParam(req,"smsFailureFirst")){
logger.info("============smsFailureFirst=================");
execOptions.setSmsOnFirstFailure(Boolean.parseBoolean(getParam(req,
"smsFailureFirst")));
}
if (hasParam(req, "smsFailureLast")) {
logger.info("============smsFailureLast=================");
execOptions.setSmsOnLastFailure(Boolean.parseBoolean(getParam(req,
"smsFailureLast")));
}
String concurrentOption = getParam(req, "concurrentOption", "skip");
execOptions.setConcurrentOption(concurrentOption);
......@@ -112,7 +156,8 @@ public class HttpRequestUtils {
if (!disabled.isEmpty()) {
// TODO edlu: see if it's possible to pass in the new format
final List<DisabledJob> disabledList =
DisabledJob.fromDeprecatedObjectList((List<Object>) JSONUtils.parseJSONFromStringQuiet(disabled));
DisabledJob.fromDeprecatedObjectList((List<Object>) JSONUtils
.parseJSONFromStringQuiet(disabled));
execOptions.setDisabledJobs(disabledList);
}
}
......@@ -268,7 +313,8 @@ public class HttpRequestUtils {
return defaultVal;
}
public static Map<String, String> getParamGroup(final HttpServletRequest request, final String groupName) {
public static Map<String, String> getParamGroup(final HttpServletRequest request,
final String groupName) throws ServletException {
final Enumeration<String> enumerate = request.getParameterNames();
final String matchString = groupName + "[";
......
......@@ -204,6 +204,13 @@ public class ExecuteFlowAction implements TriggerAction {
if (!this.executionOptions.isSuccessEmailsOverridden()) {
this.executionOptions.setSuccessEmails(flow.getSuccessEmails());
}
//添加手机号报警
if (!this.executionOptions.isFailureSmsOverride()) {
this.executionOptions.setFailureSms(flow.getFailureSms());
}
if (!this.executionOptions.isSuccessSmsOverride()) {
this.executionOptions.setSuccessSms(flow.getSuccessSms());
}
exflow.setExecutionOptions(this.executionOptions);
......
......@@ -178,7 +178,13 @@ public class EmailMessage {
props.put("mail.smtp.connectiontimeout", _connectionTimeout);
props.put("mail.smtp.starttls.enable", this._tls);
props.put("mail.smtp.ssl.trust", this._mailHost);
//添加认证协议
// props.put("mail.smtp.ssl.enable", true);
this.logger.info("打印配置文件值================================================");
props.forEach((s,x)->{
this.logger.info(s.toString()+"="+x.toString());
});
this.logger.info("============================================================");
final JavaxMailSender sender = this.creator.createSender(props);
final Message message = sender.createMessage();
......@@ -216,9 +222,12 @@ public class EmailMessage {
}
private void connectToSMTPServer(final JavaxMailSender s) throws MessagingException {
this.logger.info("host="+_mailHost+" port="+_mailPort+" user="+_mailUser+" pwd="+_mailPassword);
if (this._usesAuth) {
this.logger.info("带参");
s.connect(this._mailHost, this._mailPort, this._mailUser, this._mailPassword);
} else {
this.logger.info("不带参");
s.connect();
}
}
......
......@@ -94,6 +94,7 @@ public class Emailer extends AbstractMailer implements Alerter {
/**
* Send an email to the specified email list
* 发送电子邮件到指定的电子邮件列表
*/
public void sendEmail(final List<String> emailList, final String subject, final String body) {
if (emailList != null && !emailList.isEmpty()) {
......@@ -159,6 +160,8 @@ public class Emailer extends AbstractMailer implements Alerter {
* [mail creator] x [failure email address list]
*
* Executions with the same combo are grouped into a single message.
*
* 发送尽可能多的电子邮件,因为有独特的组合:[邮件造物主]x[失败的电子邮件地址列表]执行相同的组合,分组成一个单一的消息。
*/
@Override
public void alertOnFailedUpdate(final Executor executor, List<ExecutableFlow> flows,
......@@ -190,6 +193,7 @@ public class Emailer extends AbstractMailer implements Alerter {
/**
* Sends a single email about failed updates.
* 发送一个单一的电子邮件关于失败的更新。
*/
private void sendFailedUpdateEmail(final Executor executor,
final ExecutorManagerException exception, final MailCreator mailCreator,
......
......@@ -31,9 +31,6 @@ public class SmsAlerter implements Alerter {
sendSms(successSms, getSuccessMSG(exflow));
}
/**
* Send a message to the specified phone list
*/
public void sendSms(final List<String> phoneList, final String msg) {
if (phoneList != null && !phoneList.isEmpty()) {
for (String phone : phoneList) {
......@@ -43,6 +40,7 @@ public class SmsAlerter implements Alerter {
} else {
logger.warn("没有手机号码");
}
}
/***
......@@ -83,7 +81,7 @@ public class SmsAlerter implements Alerter {
String message = "\n\t项目%s执行失败" +
"\n\t任务ID:%s\n\t项目名:%s\n\tflow名:%s" +
"\n\t任务开始时间:%s\n\t任务结束时间:%s\n\t任务总耗时:%s" +
"\n\t失败的job:%s" +
"\n\t失败的job:%s"+
"\n\t任务状态:%s" +
"\n\t错误日志:%s";
//任务id
......@@ -130,7 +128,6 @@ public class SmsAlerter implements Alerter {
}
return failedJobs;
}
@Override
public void alertOnError(ExecutableFlow exflow, String... extraReasons) {
this.logger.info("=====================执行失败,发送手机短信===========================");
......@@ -164,5 +161,4 @@ public class SmsAlerter implements Alerter {
}
}
}
}
/*
* Copyright 2018 LinkedIn Corp.
*
* 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.
*/
* Copyright 2018 LinkedIn Corp.
*
* 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 azkaban.executor;
import static org.assertj.core.api.Assertions.assertThat;
......
......@@ -279,10 +279,24 @@ public class FlowRunner extends EventHandler implements Runnable {
Event.create(this, EventType.FLOW_FINISHED, new EventData(this.flow)));
// In polling model, executor will be responsible for sending alerting emails when a flow
// finishes.
//在轮询模型中,executor将负责在流结束时发送警告电子邮件。
// Todo jamiesjc: switch to event driven model and alert on FLOW_FINISHED event.
if (this.azkabanProps.getBoolean(ConfigurationKeys.AZKABAN_POLL_MODEL, false)) {
String[] finalizeFlowReasons = ExecutionControllerUtils.getFinalizeFlowReasons("Flow finished", null);
try {
List<String> errorLogs = ExecutionControllerUtils.getErrorLogs(flow, executorLoader);
for (String finalizeFlowReason : finalizeFlowReasons) {
String erroLine = ExecutionControllerUtils.getErroLine(finalizeFlowReason);
errorLogs.add(erroLine);
}
finalizeFlowReasons = errorLogs.toArray(new String[errorLogs.size()]);
}catch (Exception e){
e.printStackTrace();
}
ExecutionControllerUtils.alertUserOnFlowFinished(this.flow, this.alerterHolder,
ExecutionControllerUtils.getFinalizeFlowReasons("Flow finished", null));
finalizeFlowReasons, this.executorLoader);
// ExecutionControllerUtils.alertUserOnFlowFinished(this.flow, this.alerterHolder,
// ExecutionControllerUtils.getFinalizeFlowReasons("Flow finished", null),this.executorLoader);
}
}
}
......
......@@ -42,7 +42,7 @@ azkaban.jobtype.plugin.dir=/opt/azkaban3/azkaban-exec-server-0.1.0-SNAPSHOT/plug
database.type=mysql
mysql.port=3306
mysql.host=localhost
mysql.database=azkaban
mysql.database=azkaban_db
mysql.user=azkaban
mysql.password=azkaban
mysql.numconnections=100
......
......@@ -54,7 +54,6 @@ import azkaban.webapp.plugin.ViewerPlugin;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
......@@ -285,8 +284,9 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
private void handleExecutionJobDetailsPage(final HttpServletRequest req,
final HttpServletResponse resp, final Session session) throws ServletException,
IOException {
final Page page = newPage(req, resp, session,
"azkaban/webapp/servlet/velocity/jobdetailspage.vm");
final Page page =
newPage(req, resp, session,
"azkaban/webapp/servlet/velocity/jobdetailspage.vm");
final User user = session.getUser();
final int execId = getIntParam(req, "execid");
final String jobId = getParam(req, "job");
......@@ -308,7 +308,8 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
node = flow.getExecutableNodePath(jobId);
if (node == null) {
page.add("errorMsg", "Job " + jobId + " doesn't exist in " + flow.getExecutionId());
page.add("errorMsg",
"Job " + jobId + " doesn't exist in " + flow.getExecutionId());
return;
}
......@@ -657,6 +658,9 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
ret.put("successEmails", flow.getSuccessEmails());
ret.put("failureEmails", flow.getFailureEmails());
ret.put("successSms",flow.getSuccessSms());
ret.put("failureSms",flow.getFailureSms());
Schedule sflow = null;
try {
......@@ -953,6 +957,15 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
if (!options.isSuccessEmailsOverridden()) {
options.setSuccessEmails(flow.getSuccessEmails());
}
if (!options.isFailureSmsOverride()) {
if(flow.getFailureSms()!=null&&flow.getFailureSms().size()>0)
options.setFailureSms(flow.getFailureSms());
}
if (!options.isSuccessSmsOverride()) {
if(flow.getSuccessSms()!=null&&flow.getSuccessSms().size()>0)
options.setSuccessSms(flow.getSuccessSms());
}
options.setMailCreator(flow.getMailCreator());
try {
......
......@@ -26,6 +26,7 @@ import azkaban.user.UserManager;
import azkaban.user.UserManagerException;
import azkaban.utils.StringUtils;
import azkaban.webapp.WebMetrics;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
......@@ -41,6 +42,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
......
......@@ -62,7 +62,7 @@
<div class="col-xs-8">
<div id="execution-graph-options-panel">
## SVG graph panel.
## SVG graph panel.
<div id="svg-div-custom" class="side-panel">
<svg id="flow-executing-graph" xmlns="http://www.w3.org/2000/svg" version="1.1"
......@@ -70,7 +70,7 @@
</svg>
</div>
## Notification panel.
## Notification panel.
<div id="notification-panel" class="side-panel">
<h4>Notify on failure</h4>
......@@ -156,7 +156,7 @@
<textarea class="form-control" rows="3" id="success-sms"></textarea>
</div>
## Failure options panel.
## Failure options panel.
<div id="failure-options" class="side-panel">
<h4>Failure Options</h4>
......@@ -179,7 +179,7 @@
</select>
</div>
## Concurrent execution options panel.
## Concurrent execution options panel.
<div id="concurrent-panel" class="side-panel">
<h4>Concurrent Execution Options</h4>
......@@ -199,7 +199,7 @@
Run Concurrently
</label>
<span
class="help-block">Run the flow anyway. Previous execution is unaffected.</span>
class="help-block">Run the flow anyway. Previous execution is unaffected.</span>
</div>
<div class="radio">
......@@ -222,7 +222,7 @@
</div>
</div>
## Flow parameters panel
## Flow parameters panel
<div id="flow-parameters-panel" class="side-panel">
<h4>Flow Property Override</h4>
......@@ -258,13 +258,13 @@
</div>
#end
#*
#if ($triggerPlugins.size() > 0)
#foreach ($triggerPlugin in $triggerPlugins)
<button type="button" class="btn btn-default" id=set-$triggerPlugin.pluginName>$triggerPlugin.pluginName</button>
#end
#*
#if ($triggerPlugins.size() > 0)
#foreach ($triggerPlugin in $triggerPlugins)
<button type="button" class="btn btn-default" id=set-$triggerPlugin.pluginName>$triggerPlugin.pluginName</button>
#end
*#
#end
*#
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="execute-btn">Execute</button>
</div><!-- /modal-footer -->
......@@ -286,4 +286,4 @@
#end
*#
<div id="contextMenu"></div>
\ No newline at end of file
<div id="contextMenu"></div>
......@@ -39,7 +39,7 @@ lockdown.create.projects=false
cache.directory=cache
# Azkaban plugin settings
azkaban.jobtype.plugin.dir=/opt/azkaban3/azkaban-web-server-0.1.0-SNAPSHOT/plugins/jobtypes
#azkaban.jobtype.plugin.dir=/opt/azkaban3/azkaban-web-server-0.1.0-SNAPSHOT/plugins/jobtypes
# JMX stats
jetty.connector.stats=true
......@@ -55,7 +55,7 @@ executor.connector.stats=true
database.type=mysql
mysql.port=3306
mysql.host=localhost
mysql.database=azkaban
mysql.database=azkaban_db
mysql.user=azkaban
mysql.password=azkaban
mysql.numconnections=100
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment