samz406
5 years ago
committed by
GitHub
197 changed files with 2997 additions and 1501 deletions
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.alert.template; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||||
|
|
||||||
|
/** |
||||||
|
* alert message template |
||||||
|
*/ |
||||||
|
public interface AlertTemplate { |
||||||
|
|
||||||
|
/** |
||||||
|
* get a message from a specified alert template |
||||||
|
* @param content alert message content |
||||||
|
* @param showType show type |
||||||
|
* @param showAll whether to show all |
||||||
|
* @return a message from a specified alert template |
||||||
|
*/ |
||||||
|
String getMessageFromTemplate(String content, ShowType showType,boolean showAll); |
||||||
|
|
||||||
|
/** |
||||||
|
* default showAll is true |
||||||
|
*/ |
||||||
|
default String getMessageFromTemplate(String content,ShowType showType){ |
||||||
|
return getMessageFromTemplate(content,showType,true); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.alert.template; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.alert.template.impl.DefaultHTMLTemplate; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.PropertyUtils; |
||||||
|
import org.apache.dolphinscheduler.common.utils.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* the alert template factory |
||||||
|
*/ |
||||||
|
public class AlertTemplateFactory { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(AlertTemplateFactory.class); |
||||||
|
|
||||||
|
private static final String alertTemplate = PropertyUtils.getString(Constants.ALERT_TEMPLATE); |
||||||
|
|
||||||
|
private AlertTemplateFactory(){} |
||||||
|
|
||||||
|
/** |
||||||
|
* get a template from alert.properties conf file |
||||||
|
* @return a template, default is DefaultHTMLTemplate |
||||||
|
*/ |
||||||
|
public static AlertTemplate getMessageTemplate() { |
||||||
|
|
||||||
|
if(StringUtils.isEmpty(alertTemplate)){ |
||||||
|
return new DefaultHTMLTemplate(); |
||||||
|
} |
||||||
|
|
||||||
|
switch (alertTemplate){ |
||||||
|
case "html": |
||||||
|
return new DefaultHTMLTemplate(); |
||||||
|
default: |
||||||
|
throw new IllegalArgumentException(String.format("not support alert template: %s",alertTemplate)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.alert.template.impl; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.alert.template.AlertTemplate; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.MailUtils; |
||||||
|
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||||
|
import org.apache.dolphinscheduler.common.utils.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.common.utils.Preconditions.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* the default html alert message template |
||||||
|
*/ |
||||||
|
public class DefaultHTMLTemplate implements AlertTemplate { |
||||||
|
|
||||||
|
public static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplate.class); |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMessageFromTemplate(String content, ShowType showType,boolean showAll) { |
||||||
|
|
||||||
|
switch (showType){ |
||||||
|
case TABLE: |
||||||
|
return getTableTypeMessage(content,showAll); |
||||||
|
case TEXT: |
||||||
|
return getTextTypeMessage(content,showAll); |
||||||
|
default: |
||||||
|
throw new IllegalArgumentException(String.format("not support showType: %s in DefaultHTMLTemplate",showType)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get alert message which type is TABLE |
||||||
|
* @param content message content |
||||||
|
* @param showAll weather to show all |
||||||
|
* @return alert message |
||||||
|
*/ |
||||||
|
private String getTableTypeMessage(String content,boolean showAll){ |
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(content)){ |
||||||
|
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); |
||||||
|
|
||||||
|
if(!showAll && mapItemsList.size() > Constants.NUMBER_1000){ |
||||||
|
mapItemsList = mapItemsList.subList(0,Constants.NUMBER_1000); |
||||||
|
} |
||||||
|
|
||||||
|
StringBuilder contents = new StringBuilder(200); |
||||||
|
|
||||||
|
boolean flag = true; |
||||||
|
|
||||||
|
String title = ""; |
||||||
|
for (LinkedHashMap mapItems : mapItemsList){ |
||||||
|
|
||||||
|
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); |
||||||
|
|
||||||
|
Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); |
||||||
|
|
||||||
|
StringBuilder t = new StringBuilder(Constants.TR); |
||||||
|
StringBuilder cs = new StringBuilder(Constants.TR); |
||||||
|
while (iterator.hasNext()){ |
||||||
|
|
||||||
|
Map.Entry<String, Object> entry = iterator.next(); |
||||||
|
t.append(Constants.TH).append(entry.getKey()).append(Constants.TH_END); |
||||||
|
cs.append(Constants.TD).append(String.valueOf(entry.getValue())).append(Constants.TD_END); |
||||||
|
|
||||||
|
} |
||||||
|
t.append(Constants.TR_END); |
||||||
|
cs.append(Constants.TR_END); |
||||||
|
if (flag){ |
||||||
|
title = t.toString(); |
||||||
|
} |
||||||
|
flag = false; |
||||||
|
contents.append(cs); |
||||||
|
} |
||||||
|
|
||||||
|
return getMessageFromHtmlTemplate(title,contents.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get alert message which type is TEXT |
||||||
|
* @param content message content |
||||||
|
* @param showAll weather to show all |
||||||
|
* @return alert message |
||||||
|
*/ |
||||||
|
private String getTextTypeMessage(String content,boolean showAll){ |
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(content)){ |
||||||
|
List<String> list; |
||||||
|
try { |
||||||
|
list = JSONUtils.toList(content,String.class); |
||||||
|
}catch (Exception e){ |
||||||
|
logger.error("json format exception",e); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
StringBuilder contents = new StringBuilder(100); |
||||||
|
for (String str : list){ |
||||||
|
contents.append(Constants.TR); |
||||||
|
contents.append(Constants.TD).append(str).append(Constants.TD_END); |
||||||
|
contents.append(Constants.TR_END); |
||||||
|
} |
||||||
|
|
||||||
|
return getMessageFromHtmlTemplate(null,contents.toString()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get alert message from a html template |
||||||
|
* @param title message title |
||||||
|
* @param content message content |
||||||
|
* @return alert message which use html template |
||||||
|
*/ |
||||||
|
private String getMessageFromHtmlTemplate(String title,String content){ |
||||||
|
|
||||||
|
checkNotNull(content); |
||||||
|
String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>\n",title); |
||||||
|
|
||||||
|
return "<html>\n" + |
||||||
|
" <head>\n" + |
||||||
|
" <title>dolphinscheduler</title>\n" + |
||||||
|
" <meta name='Keywords' content=''>\n" + |
||||||
|
" <meta name='Description' content=''>\n" + |
||||||
|
" <style type=\"text/css\">\n" + |
||||||
|
" table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}\n" + |
||||||
|
" table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: right;}\n" + |
||||||
|
" table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: right;}\n" + |
||||||
|
" </style>\n" + |
||||||
|
" </head>\n" + |
||||||
|
" <body style=\"margin:0;padding:0\">\n" + |
||||||
|
" <table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\">\n" + htmlTableThead + content + |
||||||
|
" </table>\n" + |
||||||
|
" </body>\n" + |
||||||
|
"</html>"; |
||||||
|
} |
||||||
|
} |
@ -1,17 +0,0 @@ |
|||||||
<#-- |
|
||||||
~ Licensed to the Apache Software Foundation (ASF) under one or more |
|
||||||
~ contributor license agreements. See the NOTICE file distributed with |
|
||||||
~ this work for additional information regarding copyright ownership. |
|
||||||
~ The ASF licenses this file to You 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. |
|
||||||
--> |
|
||||||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><html><head><title> dolphinscheduler</title><meta name='Keywords' content=''><meta name='Description' content=''><style type="text/css">table { margin-top:0px; padding-top:0px; border:1px solid; font-size: 14px; color: #333333; border-width: 1px; border-color: #666666; border-collapse: collapse; } table th { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #dedede; text-align: right;} table td { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #ffffff; text-align: right;}</style></head><body style="margin:0;padding:0"><table border="1px" cellpadding="5px" cellspacing="-10px"><thead><#if title??> ${title}</#if></thead><#if content??> ${content}</#if></table></body></html> |
|
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.alert.template; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.alert.template.impl.DefaultHTMLTemplate; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.Constants; |
||||||
|
import org.apache.dolphinscheduler.alert.utils.PropertyUtils; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
import org.powermock.api.mockito.PowerMockito; |
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
||||||
|
import org.powermock.modules.junit4.PowerMockRunner; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import static org.mockito.Mockito.*; |
||||||
|
import static org.junit.Assert.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* test class for AlertTemplateFactory |
||||||
|
*/ |
||||||
|
@RunWith(PowerMockRunner.class) |
||||||
|
@PrepareForTest(PropertyUtils.class) |
||||||
|
public class AlertTemplateFactoryTest { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(AlertTemplateFactoryTest.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* GetMessageTemplate method test |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testGetMessageTemplate(){ |
||||||
|
|
||||||
|
PowerMockito.mockStatic(PropertyUtils.class); |
||||||
|
when(PropertyUtils.getString(Constants.ALERT_TEMPLATE)).thenReturn("html"); |
||||||
|
|
||||||
|
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate(); |
||||||
|
|
||||||
|
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* GetMessageTemplate method throw Exception test |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testGetMessageTemplateException(){ |
||||||
|
|
||||||
|
AlertTemplate defaultTemplate = AlertTemplateFactory.getMessageTemplate(); |
||||||
|
assertTrue(defaultTemplate instanceof DefaultHTMLTemplate); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.alert.template.impl; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.alert.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.common.enums.ShowType; |
||||||
|
import org.junit.Test; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.junit.Assert.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* test class for DefaultHTMLTemplate |
||||||
|
*/ |
||||||
|
public class DefaultHTMLTemplateTest{ |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplateTest.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* only need test method GetMessageFromTemplate |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testGetMessageFromTemplate(){ |
||||||
|
|
||||||
|
DefaultHTMLTemplate template = new DefaultHTMLTemplate(); |
||||||
|
|
||||||
|
String tableTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TABLE,true); |
||||||
|
|
||||||
|
assertEquals(tableTypeMessage,generateMockTableTypeResultByHand()); |
||||||
|
|
||||||
|
String textTypeMessage = template.getMessageFromTemplate(list2String(), ShowType.TEXT,true); |
||||||
|
|
||||||
|
assertEquals(textTypeMessage,generateMockTextTypeResultByHand()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* generate some simulation data |
||||||
|
*/ |
||||||
|
private String list2String(){ |
||||||
|
|
||||||
|
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>(); |
||||||
|
map1.put("mysql service name","mysql200"); |
||||||
|
map1.put("mysql address","192.168.xx.xx"); |
||||||
|
map1.put("port","3306"); |
||||||
|
map1.put("no index of number","80"); |
||||||
|
map1.put("database client connections","190"); |
||||||
|
|
||||||
|
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>(); |
||||||
|
map2.put("mysql service name","mysql210"); |
||||||
|
map2.put("mysql address","192.168.xx.xx"); |
||||||
|
map2.put("port","3306"); |
||||||
|
map2.put("no index of number","10"); |
||||||
|
map2.put("database client connections","90"); |
||||||
|
|
||||||
|
List<LinkedHashMap<String, Object>> maps = new ArrayList<>(); |
||||||
|
maps.add(0,map1); |
||||||
|
maps.add(1,map2); |
||||||
|
String mapjson = JSONUtils.toJsonString(maps); |
||||||
|
logger.info(mapjson); |
||||||
|
|
||||||
|
return mapjson; |
||||||
|
} |
||||||
|
|
||||||
|
private String generateMockTableTypeResultByHand(){ |
||||||
|
|
||||||
|
return "<html>\n" + |
||||||
|
" <head>\n" + |
||||||
|
" <title>dolphinscheduler</title>\n" + |
||||||
|
" <meta name='Keywords' content=''>\n" + |
||||||
|
" <meta name='Description' content=''>\n" + |
||||||
|
" <style type=\"text/css\">\n" + |
||||||
|
" table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}\n" + |
||||||
|
" table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: right;}\n" + |
||||||
|
" table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: right;}\n" + |
||||||
|
" </style>\n" + |
||||||
|
" </head>\n" + |
||||||
|
" <body style=\"margin:0;padding:0\">\n" + |
||||||
|
" <table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\">\n" + |
||||||
|
"<thead><tr><th>mysql service name</th><th>mysql address</th><th>port</th><th>no index of number</th><th>database client connections</th></tr></thead>\n" + |
||||||
|
"<tr><td>mysql200</td><td>192.168.xx.xx</td><td>3306</td><td>80</td><td>190</td></tr><tr><td>mysql210</td><td>192.168.xx.xx</td><td>3306</td><td>10</td><td>90</td></tr> </table>\n" + |
||||||
|
" </body>\n" + |
||||||
|
"</html>"; |
||||||
|
} |
||||||
|
|
||||||
|
private String generateMockTextTypeResultByHand(){ |
||||||
|
|
||||||
|
return "<html>\n" + |
||||||
|
" <head>\n" + |
||||||
|
" <title>dolphinscheduler</title>\n" + |
||||||
|
" <meta name='Keywords' content=''>\n" + |
||||||
|
" <meta name='Description' content=''>\n" + |
||||||
|
" <style type=\"text/css\">\n" + |
||||||
|
" table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}\n" + |
||||||
|
" table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: right;}\n" + |
||||||
|
" table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: right;}\n" + |
||||||
|
" </style>\n" + |
||||||
|
" </head>\n" + |
||||||
|
" <body style=\"margin:0;padding:0\">\n" + |
||||||
|
" <table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\">\n" + |
||||||
|
"<tr><td>{\"mysql service name\":\"mysql200\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"190\",\"port\":\"3306\",\"no index of number\":\"80\"}</td></tr><tr><td>{\"mysql service name\":\"mysql210\",\"mysql address\":\"192.168.xx.xx\",\"database client connections\":\"90\",\"port\":\"3306\",\"no index of number\":\"10\"}</td></tr> </table>\n" + |
||||||
|
" </body>\n" + |
||||||
|
"</html>"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.EnumValue; |
||||||
|
|
||||||
|
/** |
||||||
|
* authentication type |
||||||
|
*/ |
||||||
|
public enum AuthenticationType { |
||||||
|
|
||||||
|
PASSWORD(0, "verify via user name and password"), |
||||||
|
; |
||||||
|
|
||||||
|
AuthenticationType(int code, String desc) { |
||||||
|
this.code = code; |
||||||
|
this.desc = desc; |
||||||
|
} |
||||||
|
|
||||||
|
@EnumValue |
||||||
|
private final int code; |
||||||
|
private final String desc; |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public interface Authenticator { |
||||||
|
/** |
||||||
|
* Verifying legality via username and password |
||||||
|
* @param username user name |
||||||
|
* @param password user password |
||||||
|
* @param extra extra info |
||||||
|
* @return result object |
||||||
|
*/ |
||||||
|
Result<Map<String, String>> authenticate(String username, String password, String extra); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get authenticated user |
||||||
|
* @param request http servlet request |
||||||
|
* @return user |
||||||
|
*/ |
||||||
|
User getAuthUser(HttpServletRequest request); |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.enums.Status; |
||||||
|
import org.apache.dolphinscheduler.api.service.SessionService; |
||||||
|
import org.apache.dolphinscheduler.api.service.UsersService; |
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.common.Constants; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.Session; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class PasswordAuthenticator implements Authenticator { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PasswordAuthenticator.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UsersService userService; |
||||||
|
@Autowired |
||||||
|
private SessionService sessionService; |
||||||
|
|
||||||
|
@Override |
||||||
|
public Result<Map<String, String>> authenticate(String username, String password, String extra) { |
||||||
|
Result<Map<String, String>> result = new Result<>(); |
||||||
|
// verify username and password
|
||||||
|
User user = userService.queryUser(username, password); |
||||||
|
if (user == null) { |
||||||
|
result.setCode(Status.USER_NAME_PASSWD_ERROR.getCode()); |
||||||
|
result.setMsg(Status.USER_NAME_PASSWD_ERROR.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
// create session
|
||||||
|
String sessionId = sessionService.createSession(user, extra); |
||||||
|
if (sessionId == null) { |
||||||
|
result.setCode(Status.LOGIN_SESSION_FAILED.getCode()); |
||||||
|
result.setMsg(Status.LOGIN_SESSION_FAILED.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
logger.info("sessionId : {}" , sessionId); |
||||||
|
result.setData(Collections.singletonMap(Constants.SESSION_ID, sessionId)); |
||||||
|
result.setCode(Status.SUCCESS.getCode()); |
||||||
|
result.setMsg(Status.LOGIN_SUCCESS.getMsg()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public User getAuthUser(HttpServletRequest request) { |
||||||
|
Session session = sessionService.getSession(request); |
||||||
|
if (session == null) { |
||||||
|
logger.info("session info is null "); |
||||||
|
return null; |
||||||
|
} |
||||||
|
//get user object from session
|
||||||
|
return userService.queryUser(session.getUserId()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class SecurityConfig { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); |
||||||
|
|
||||||
|
@Value("${security.authentication.type:PASSWORD}") |
||||||
|
private String type; |
||||||
|
|
||||||
|
private AutowireCapableBeanFactory beanFactory; |
||||||
|
private AuthenticationType authenticationType; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
public SecurityConfig(AutowireCapableBeanFactory beanFactory) { |
||||||
|
this.beanFactory = beanFactory; |
||||||
|
} |
||||||
|
|
||||||
|
private void setAuthenticationType(String type) { |
||||||
|
if (StringUtils.isBlank(type)) { |
||||||
|
logger.info("security.authentication.type configuration is empty, the default value 'PASSWORD'"); |
||||||
|
this.authenticationType = AuthenticationType.PASSWORD; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
this.authenticationType = AuthenticationType.valueOf(type); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean(name = "authenticator") |
||||||
|
public Authenticator authenticator() { |
||||||
|
setAuthenticationType(type); |
||||||
|
Authenticator authenticator; |
||||||
|
switch (authenticationType) { |
||||||
|
case PASSWORD: |
||||||
|
authenticator = new PasswordAuthenticator(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new IllegalStateException("Unexpected value: " + authenticationType); |
||||||
|
} |
||||||
|
beanFactory.autowireBean(authenticator); |
||||||
|
return authenticator; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.interceptor; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.apache.dolphinscheduler.api.security.Authenticator; |
||||||
|
import org.apache.dolphinscheduler.common.enums.UserType; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.apache.dolphinscheduler.dao.mapper.UserMapper; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import static org.mockito.Mockito.when; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
public class LoginHandlerInterceptorTest { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LoginHandlerInterceptorTest.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
LoginHandlerInterceptor interceptor; |
||||||
|
@MockBean |
||||||
|
private Authenticator authenticator; |
||||||
|
@MockBean |
||||||
|
private UserMapper userMapper; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPreHandle() { |
||||||
|
HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
||||||
|
HttpServletResponse response = Mockito.mock(HttpServletResponse.class); |
||||||
|
// test no token and no cookie
|
||||||
|
Assert.assertFalse(interceptor.preHandle(request, response, null)); |
||||||
|
|
||||||
|
User mockUser = new User(); |
||||||
|
mockUser.setId(1); |
||||||
|
mockUser.setUserType(UserType.GENERAL_USER); |
||||||
|
|
||||||
|
// test no token
|
||||||
|
when(authenticator.getAuthUser(request)).thenReturn(mockUser); |
||||||
|
Assert.assertTrue(interceptor.preHandle(request, response, null)); |
||||||
|
|
||||||
|
// test token
|
||||||
|
String token = "123456"; |
||||||
|
when(request.getHeader("token")).thenReturn(token); |
||||||
|
when(userMapper.queryUserByToken(token)).thenReturn(mockUser); |
||||||
|
Assert.assertTrue(interceptor.preHandle(request, response, null)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.apache.dolphinscheduler.api.enums.Status; |
||||||
|
import org.apache.dolphinscheduler.api.service.SessionService; |
||||||
|
import org.apache.dolphinscheduler.api.service.UsersService; |
||||||
|
import org.apache.dolphinscheduler.api.utils.Result; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.Session; |
||||||
|
import org.apache.dolphinscheduler.dao.entity.User; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
import static org.mockito.Mockito.*; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
public class PasswordAuthenticatorTest { |
||||||
|
private static Logger logger = LoggerFactory.getLogger(PasswordAuthenticatorTest.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private AutowireCapableBeanFactory beanFactory; |
||||||
|
@MockBean |
||||||
|
private SessionService sessionService; |
||||||
|
@MockBean |
||||||
|
private UsersService usersService; |
||||||
|
|
||||||
|
private PasswordAuthenticator authenticator; |
||||||
|
|
||||||
|
private User mockUser; |
||||||
|
private Session mockSession; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() throws Exception { |
||||||
|
authenticator = new PasswordAuthenticator(); |
||||||
|
beanFactory.autowireBean(authenticator); |
||||||
|
|
||||||
|
mockUser = new User(); |
||||||
|
mockUser.setUserName("test"); |
||||||
|
mockUser.setEmail("test@test.com"); |
||||||
|
mockUser.setUserPassword("test"); |
||||||
|
mockUser.setId(1); |
||||||
|
|
||||||
|
mockSession = new Session(); |
||||||
|
mockSession.setId(UUID.randomUUID().toString()); |
||||||
|
mockSession.setIp("127.0.0.1"); |
||||||
|
mockSession.setUserId(1); |
||||||
|
mockSession.setLastLoginTime(new Date()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAuthenticate() { |
||||||
|
when(usersService.queryUser("test", "test")).thenReturn(mockUser); |
||||||
|
when(sessionService.createSession(mockUser, "127.0.0.1")).thenReturn(mockSession.getId()); |
||||||
|
Result result = authenticator.authenticate("test", "test", "127.0.0.1"); |
||||||
|
Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); |
||||||
|
logger.info(result.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGetAuthUser() { |
||||||
|
HttpServletRequest request = Mockito.mock(HttpServletRequest.class); |
||||||
|
when(usersService.queryUser(mockUser.getId())).thenReturn(mockUser); |
||||||
|
when(sessionService.getSession(request)).thenReturn(mockSession); |
||||||
|
|
||||||
|
User user = authenticator.getAuthUser(request); |
||||||
|
Assert.assertNotNull(user); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.api.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.api.ApiApplicationServer; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
import org.springframework.test.context.TestPropertySource; |
||||||
|
import org.springframework.test.context.junit4.SpringRunner; |
||||||
|
|
||||||
|
@RunWith(SpringRunner.class) |
||||||
|
@SpringBootTest(classes = ApiApplicationServer.class) |
||||||
|
@TestPropertySource(properties = { |
||||||
|
"security.authentication.type=PASSWORD", |
||||||
|
}) |
||||||
|
public class SecurityConfigTest { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private SecurityConfig securityConfig; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAuthenticator() { |
||||||
|
Authenticator authenticator = securityConfig.authenticator(); |
||||||
|
Assert.assertNotNull(authenticator); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.common.utils; |
||||||
|
|
||||||
|
|
||||||
|
public class ArrayUtils { |
||||||
|
|
||||||
|
public static boolean isEmpty(final int[] array) { |
||||||
|
return array == null || array.length == 0; |
||||||
|
} |
||||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,45 @@ |
|||||||
|
|
||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.common.utils; |
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
|
||||||
|
public class IOUtils { |
||||||
|
|
||||||
|
public static void closeQuietly(InputStream fis){ |
||||||
|
if(fis != null){ |
||||||
|
try { |
||||||
|
fis.close(); |
||||||
|
} catch (IOException ignore) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void closeQuietly(InputStreamReader reader){ |
||||||
|
if(reader != null){ |
||||||
|
try { |
||||||
|
reader.close(); |
||||||
|
} catch (IOException ignore) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,170 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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.dolphinscheduler.common.utils; |
||||||
|
|
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import static org.hamcrest.core.StringContains.containsString; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
import static org.junit.Assert.assertThat; |
||||||
|
|
||||||
|
|
||||||
|
public class PreconditionsTest { |
||||||
|
public static final Logger logger = LoggerFactory.getLogger(PreconditionsTest.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* Test checkNotNull |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testCheckNotNull() throws Exception { |
||||||
|
String testReference = "test reference"; |
||||||
|
//test reference is not null
|
||||||
|
Assert.assertEquals(testReference,Preconditions.checkNotNull(testReference)); |
||||||
|
Assert.assertEquals(testReference,Preconditions.checkNotNull(testReference,"reference is null")); |
||||||
|
Assert.assertEquals(testReference,Preconditions.checkNotNull(testReference,"%s is null",testReference)); |
||||||
|
|
||||||
|
//test reference is null
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull(null); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertNull(ex.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull(""); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertNull(ex.getMessage()); |
||||||
|
} |
||||||
|
//test reference is null ,expect contains errorMessage
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull(null,"reference is null"); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("reference is null")); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull("","reference is null"); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("reference is null")); |
||||||
|
} |
||||||
|
|
||||||
|
//test reference is null ,expect contains errorMessageTemplate and errorMessageArgs
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull(null,"%s is null",testReference); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString(testReference + " is null")); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
Preconditions.checkNotNull("","%s is null",testReference); |
||||||
|
} catch (NullPointerException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString(testReference + " is null")); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test checkArgument |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testCheckArgument() throws Exception { |
||||||
|
|
||||||
|
int argument = 100; |
||||||
|
//boolean condition is true
|
||||||
|
Preconditions.checkArgument(argument > 0 && argument < 200); |
||||||
|
|
||||||
|
//boolean condition is false
|
||||||
|
try { |
||||||
|
Preconditions.checkArgument(argument > 0 && argument < 50); |
||||||
|
} catch (IllegalArgumentException ex) { |
||||||
|
assertNull(ex.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
//boolean condition is false ,expect contains errorMessage
|
||||||
|
try { |
||||||
|
Preconditions.checkArgument(argument > 300, "argument is error"); |
||||||
|
} catch (IllegalArgumentException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("argument is error")); |
||||||
|
} |
||||||
|
|
||||||
|
//boolean condition is false,expect contains errorMessageTemplate and errorMessageArgs
|
||||||
|
try { |
||||||
|
Preconditions.checkArgument(argument > 0 && argument < 99, "argument %s is error",argument); |
||||||
|
} catch (IllegalArgumentException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString( "argument " + argument + " is error")); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test checkState |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testCheckState() throws Exception { |
||||||
|
int state = 1; |
||||||
|
//boolean condition is true
|
||||||
|
Preconditions.checkState(state == 1); |
||||||
|
Preconditions.checkState(state > -1); |
||||||
|
|
||||||
|
//boolean condition is false
|
||||||
|
try { |
||||||
|
Preconditions.checkState(state > 2); |
||||||
|
} catch (IllegalStateException ex) { |
||||||
|
assertNull(ex.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
//boolean condition is false ,expect contains errorMessage
|
||||||
|
try { |
||||||
|
Preconditions.checkState(state < 1, "state is error"); |
||||||
|
} catch (IllegalStateException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("state is error")); |
||||||
|
} |
||||||
|
|
||||||
|
//boolean condition is false,expect contains errorMessageTemplate and errorMessageArgs
|
||||||
|
try { |
||||||
|
Preconditions.checkState(state < -1 , "state %s is error",state); |
||||||
|
} catch (IllegalStateException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString( "state " + state + " is error")); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test checkElementIndex |
||||||
|
*/ |
||||||
|
@Test |
||||||
|
public void testCheckElementIndex() throws Exception { |
||||||
|
int index = 2; |
||||||
|
int size = 30; |
||||||
|
|
||||||
|
//boolean condition is true
|
||||||
|
Preconditions.checkElementIndex(index, size); |
||||||
|
|
||||||
|
//boolean condition is false
|
||||||
|
try { |
||||||
|
Preconditions.checkElementIndex(-1, 10); |
||||||
|
} catch (IndexOutOfBoundsException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("Index: -1, Size: 10")); |
||||||
|
} |
||||||
|
|
||||||
|
//boolean condition is false ,expect contains errorMessage
|
||||||
|
try { |
||||||
|
Preconditions.checkElementIndex(100, 50, "index is greater than size"); |
||||||
|
} catch (IndexOutOfBoundsException ex) { |
||||||
|
assertThat(ex.getMessage(), containsString("index is greater than size Index: 100, Size: 50")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue