├── .gitignore ├── LICENSE ├── README.md ├── build.xml ├── conf ├── configure.properties └── ip.xls ├── demo ├── addhostcmd.gif ├── addhostxls.gif ├── delhost.gif ├── excel.png ├── excelcmd.gif ├── excelupload.gif ├── execmd.gif ├── jh.gif ├── jhcmd.gif ├── jhupload.gif ├── listhost.gif └── uploadfile.gif ├── lib ├── commons-cli-1.2.jar ├── commons-logging-1.2.jar ├── javabase64-1.3.1.jar ├── jsch-0.1.51.jar ├── jxl.jar ├── log4j-1.2.9.jar └── sqlite.jar ├── release └── easyxms-1.0.zip ├── scripts ├── start.bat └── start.sh └── src ├── commons-logging.properties ├── log4j.properties └── org └── easyxms ├── ActionForChoiceNumber.java ├── ChoiceNumber.java ├── CommandLineAction.java ├── CommandLineOptionsParser.java ├── ConnectServer.java ├── DBManager.java ├── EasyXMS.java ├── EncryptDecryptPassword.java ├── ExecCommand.java ├── FileTransferProgressMonitor.java ├── FunctionKit.java ├── GetIPInfoFromExcel.java ├── GetIPInfoFromFile.java ├── GetInput.java ├── HelpPrompt.java ├── MultiThread.java ├── Quit.java ├── ResultSetToEntityMapping.java ├── ServerInfo.java ├── ServerInfoDAO.java ├── ServerInfoMapping.java ├── SessionPool.java ├── SettingInfo.java ├── TransferFile.java ├── UploadFile.java └── WriteLog.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | EasyXMS.iml 3 | .idea 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | src/com/linux178 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | EasyXMS 2 | ------- 3 | 4 | EasyXMS是一个Java编写的用于批量管理Linux服务器的简易系统,如:多线程批量执行命令、多线程批量上传文件等功能. 5 | 6 | 2种使用模式: 7 | 8 | 9 | 1.交互模式执行动作 10 | 2.直接在命令行执行动作 11 | 12 | 13 | 一、运行环境 14 | ------- 15 | 16 | JDK1.6+ 17 | 18 | 二、注意事项 19 | ------- 20 | 21 | 1.在sshd配置文件/etc/ssh/sshd_config中 UseDNS yes 修改为 UseDNS no,可以确保连接顺畅 22 | 2.像执行时间过长的命令,如top、yum这类命令不适合执行 23 | 3.进入到项目的目录,使用Ant来编译打包 24 | 25 | 26 | 三、交互模式执行动作效果演示 27 | -------------------- 28 | 29 | ### 1.主菜单 30 | ![交互模式](demo/jh.gif) 31 | 32 | ### 2.批量执行命令 33 | ![交互模式](demo/jhcmd.gif) 34 | 35 | ### 3.批量上传文件 36 | ![交互模式](demo/jhupload.gif) 37 | 38 | 39 | 四、命令行执行动作效果演示 40 | -------------------- 41 | 42 | 演示在window系统上演示 43 | 44 | ### 1.批量执行命令 45 | 46 | IP地址、分组、用户名、密码和端口事先添加到程序的数据库中 47 | 48 | ![执行命令](demo/execmd.gif) 49 | 50 | 51 | ### 2.批量上传文件 52 | 53 | IP地址、分组、用户名、密码和端口事先添加到程序的数据库中 54 | 55 | ![上传文件](demo/uploadfile.gif) 56 | 57 | 58 | ### 3.直接读取Excel文件的信息批量执行命令 59 | 60 | Excel文件中包含IP地址、分组、用户名、密码和端口 61 | 62 | ![执行命令](demo/excelcmd.gif) 63 | 64 | 65 | ### 4.直接读取Excel文件的信息批量上传文件 66 | 67 | Excel文件中包含IP地址、分组、用户名、密码和端口 68 | 69 | ![上传文件](demo/excelupload.gif) 70 | 71 | 72 | 73 | 五、添加删除IP信息效果演示 74 | ----------------------- 75 | 76 | ### 1.添加IP信息 77 | 78 | IP地址、分组、用户名、密码和端口,添加到程序的数据库中 79 | 80 | 从命令行添加 81 | 82 | ![添加IP](demo/addhostcmd.gif) 83 | 84 | 从Excel文件中添加 85 | 86 | ![添加IP](demo/addhostxls.gif) 87 | 88 | Excel文件的模板 89 | 90 | ![添加IP](demo/excel.png) 91 | 92 | ### 2.删除IP信息 93 | 94 | ![删除IP信息](demo/delhost.gif) 95 | 96 | 97 | ### 3.列出IP信息 98 | 99 | ![列出IP信息](demo/listhost.gif) -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /conf/configure.properties: -------------------------------------------------------------------------------- 1 | #### Connect TimeOut Time. Unit: ms #### 2 | connect_time_out=3000 3 | 4 | #### Enable HTTP Proxy 0:disable 1:enable#### 5 | enable_http_proxy=0 6 | http_proxy_server=proxy.baidu.com 7 | http_proxy_port=80 8 | 9 | #### ChildThread of the sleep time, is used to obtain the ChildThread command execution results, #### 10 | #### time is too short, cannot obtain. Unit: ms #### 11 | sleep_time=300 12 | -------------------------------------------------------------------------------- /conf/ip.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/conf/ip.xls -------------------------------------------------------------------------------- /demo/addhostcmd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/addhostcmd.gif -------------------------------------------------------------------------------- /demo/addhostxls.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/addhostxls.gif -------------------------------------------------------------------------------- /demo/delhost.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/delhost.gif -------------------------------------------------------------------------------- /demo/excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/excel.png -------------------------------------------------------------------------------- /demo/excelcmd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/excelcmd.gif -------------------------------------------------------------------------------- /demo/excelupload.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/excelupload.gif -------------------------------------------------------------------------------- /demo/execmd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/execmd.gif -------------------------------------------------------------------------------- /demo/jh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/jh.gif -------------------------------------------------------------------------------- /demo/jhcmd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/jhcmd.gif -------------------------------------------------------------------------------- /demo/jhupload.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/jhupload.gif -------------------------------------------------------------------------------- /demo/listhost.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/listhost.gif -------------------------------------------------------------------------------- /demo/uploadfile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/demo/uploadfile.gif -------------------------------------------------------------------------------- /lib/commons-cli-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/commons-cli-1.2.jar -------------------------------------------------------------------------------- /lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /lib/javabase64-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/javabase64-1.3.1.jar -------------------------------------------------------------------------------- /lib/jsch-0.1.51.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/jsch-0.1.51.jar -------------------------------------------------------------------------------- /lib/jxl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/jxl.jar -------------------------------------------------------------------------------- /lib/log4j-1.2.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/log4j-1.2.9.jar -------------------------------------------------------------------------------- /lib/sqlite.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/lib/sqlite.jar -------------------------------------------------------------------------------- /release/easyxms-1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/release/easyxms-1.0.zip -------------------------------------------------------------------------------- /scripts/start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if "%1" == "" ( 4 | java -jar easyxms.jar 5 | ) else ( 6 | java -jar easyxms.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 7 | ) 8 | -------------------------------------------------------------------------------- /scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | if /usr/bin/which java &>/dev/null; then 5 | version=`java -version 2>&1 | awk 'NR==1{print $3}'` 6 | current_java_version=${version:1:3} 7 | if [[ ${current_java_version} > 1.5 ]];then 8 | if [[ $# == 0 ]];then 9 | java -jar easyxms.jar 10 | else 11 | java -jar easyxms.jar "$@" 12 | fi 13 | else 14 | echo "Java Version Not Matched,Please Install JDK/JRE 1.6+" 15 | fi 16 | else 17 | echo "Java not Found,Please Install JDK/JRE 1.6+" 18 | fi -------------------------------------------------------------------------------- /src/commons-logging.properties: -------------------------------------------------------------------------------- 1 | org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger -------------------------------------------------------------------------------- /src/log4j.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chanyipiaomiao/EasyXMS/9f1e1d3b48c222681c99481eed325e7ff4282cf1/src/log4j.properties -------------------------------------------------------------------------------- /src/org/easyxms/ActionForChoiceNumber.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.Session; 5 | import java.io.File; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | 10 | 11 | /** 12 | * 按对应的数字执行相对应的动作 13 | */ 14 | class ActionForChoiceNumber { 15 | 16 | 17 | /** 18 | * 从命令行读取输入 19 | * @return 一个字符串 20 | */ 21 | String getInputContent(){ 22 | GetInput getInput = new GetInput(); 23 | return getInput.getInputFromStandardInput(); 24 | } 25 | 26 | 27 | /** 28 | * 把字符串转换为一个对象 29 | * @param host 主机信息字符串 30 | * @return ServerInfo对象 31 | */ 32 | ServerInfo stringToObject(String host){ 33 | ServerInfo serverInfo = null; 34 | String[] host_infos = host.split("\\s+"); 35 | if (host_infos.length == 5){ 36 | String ip = host_infos[0]; 37 | if (FunctionKit.checkStringIsIP(ip)){ 38 | String group = host_infos[1]; 39 | String username = EncryptDecryptPassword.Encrypt(host_infos[2]); 40 | String password = EncryptDecryptPassword.Encrypt(host_infos[3]); 41 | int port = Integer.parseInt(host_infos[4]); 42 | serverInfo = new ServerInfo(ip,group,username,password,port); 43 | } else { 44 | HelpPrompt.printInputError(); 45 | } 46 | } else { 47 | HelpPrompt.printInputError(); 48 | } 49 | return serverInfo; 50 | } 51 | 52 | 53 | /** 54 | * 从命令行增加一台服务器信息 55 | * @param serverInfoDAO ServerInfo数据库访问对象 56 | */ 57 | void addServerFromCommandLine(ServerInfoDAO serverInfoDAO){ 58 | 59 | HelpPrompt.printAddServer(); 60 | String input = getInputContent(); 61 | List objects = new ArrayList(); 62 | 63 | if (input.contains(";")){ 64 | String hosts[] = input.trim().split(";"); 65 | for (String host : hosts){ 66 | ServerInfo serverInfo = stringToObject(host); 67 | if (serverInfo != null){ 68 | objects.add(serverInfo); 69 | } 70 | } 71 | } else { 72 | ServerInfo serverInfo = stringToObject(input); 73 | if (serverInfo != null){ 74 | objects.add(serverInfo); 75 | } 76 | } 77 | 78 | if (objects.size() != 0){ 79 | serverInfoDAO.insert(objects); 80 | } 81 | } 82 | 83 | 84 | /** 85 | * 从Excel文件中添加服务器信息 86 | * @param serverInfoDAO ServerInfo数据库访问对象 87 | */ 88 | void addServerFromExcelFile(ServerInfoDAO serverInfoDAO){ 89 | HelpPrompt.printExcelFilePath(); 90 | String ask_excel_file = getInputContent(); 91 | if (! FunctionKit.checkStringLengthIsZero(ask_excel_file)){ 92 | HelpPrompt.printInputError(); 93 | } else { 94 | GetIPInfoFromFile getIPInfoFromFile = new GetIPInfoFromExcel(); 95 | List objects = getIPInfoFromFile.getIPInfo(ask_excel_file); 96 | if (objects.size() != 0){ 97 | serverInfoDAO.insert(objects); 98 | } 99 | } 100 | } 101 | 102 | 103 | /** 104 | * 列出数据库中的服务器信息(IP Group) 105 | * @param serverInfoDAO ServerInfo数据库访问对象 106 | */ 107 | void listIPGroupFromDatabase(ServerInfoDAO serverInfoDAO){ 108 | if (serverInfoDAO.queryAll().size() == 0){ 109 | HelpPrompt.printNoDataInDataBase(); 110 | } else { 111 | HelpPrompt.printListServer(); 112 | String ask_list_group = getInputContent(); 113 | if (! FunctionKit.checkStringLengthIsZero(ask_list_group)){ 114 | HelpPrompt.printInputError(); 115 | } else { 116 | String list_group[] = ask_list_group.split("\\s+"); 117 | if (list_group.length == 1 && "all".equals(list_group[0])){ 118 | List result = serverInfoDAO.queryIPServerGroup(); 119 | for (String ip_group : result){ 120 | System.out.println(ip_group); 121 | } 122 | } else { 123 | for (String group_name : list_group){ 124 | if (serverInfoDAO.queryAllFieldByServerGroup(group_name).size() != 0){ 125 | for (String ip_group : serverInfoDAO.queryIPServerGroupByServerGroup(group_name)){ 126 | System.out.println(ip_group); 127 | } 128 | } else { 129 | HelpPrompt.printIpOrGroupNotExists(group_name); 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | 137 | 138 | /** 139 | * 列出数据库中的分组 140 | * @param serverInfoDAO ServerInfo数据库访问对象 141 | */ 142 | void listGroupFromDatabase(ServerInfoDAO serverInfoDAO){ 143 | if (serverInfoDAO.queryAll().size() == 0){ 144 | HelpPrompt.printNoDataInDataBase(); 145 | } else { 146 | List result = serverInfoDAO.queryDistinctServerGroup(); 147 | for (String group : result){ 148 | System.out.println(group); 149 | } 150 | } 151 | } 152 | 153 | 154 | /** 155 | * 删除指定的服务器信息 156 | * @param serverInfoDAO ServerInfo数据库访问对象 157 | */ 158 | void deleteServerInfoFromDatabase(ServerInfoDAO serverInfoDAO){ 159 | if (serverInfoDAO.queryAll().size() == 0){ 160 | HelpPrompt.printNoDataInDataBase(); 161 | } else { 162 | HelpPrompt.printSpecifyIPOrGroupOrAllForDelete(); 163 | String ask_delete_ip_or_group = getInputContent(); 164 | if (! FunctionKit.checkStringLengthIsZero(ask_delete_ip_or_group)){ 165 | HelpPrompt.printInputError(); 166 | } else { 167 | String delete_ip_group[] = ask_delete_ip_or_group.split("\\s+"); 168 | if (delete_ip_group.length == 1 && "all".equals(delete_ip_group[0])){ 169 | HelpPrompt.printAskClearTable(); 170 | String ask_clear_all_server = getInputContent(); 171 | if ("y".equals(ask_clear_all_server) || "Y".equals(ask_clear_all_server)){ 172 | serverInfoDAO.deleteAll(); 173 | } else { 174 | HelpPrompt.printNothingHappen(); 175 | } 176 | } else { 177 | for (String ip_or_group : delete_ip_group){ 178 | if (FunctionKit.checkStringIsIP(ip_or_group)){ 179 | serverInfoDAO.deleteByIP(ip_or_group); 180 | } else { 181 | serverInfoDAO.deleteByServerGroup(ip_or_group); 182 | } 183 | } 184 | } 185 | } 186 | } 187 | } 188 | 189 | 190 | /** 191 | * 为连接服务器做准备 192 | * @param serverInfoDAO ServerInfo数据库访问对象 193 | * @param ssh_sftp 用来标识连接的动作 是 ssh 还是 sftp 194 | */ 195 | void connectServerForSSHSFTP(ServerInfoDAO serverInfoDAO,String ssh_sftp){ 196 | if (serverInfoDAO.queryAll().size() == 0){ 197 | HelpPrompt.printNoDataInDataBase(); 198 | } else { 199 | HelpPrompt.printListIPOrGroupOrAllForExec(); 200 | String ask_server = getInputContent(); 201 | if (! FunctionKit.checkStringLengthIsZero(ask_server)){ 202 | HelpPrompt.printInputError(); 203 | } else { 204 | String ip_or_group_array[] = ask_server.split("\\s+"); 205 | List objects = new ArrayList(); 206 | boolean check_occur_error = false; 207 | if (ip_or_group_array.length == 1 && "all".equals(ip_or_group_array[0])){ 208 | objects = serverInfoDAO.queryAll(); 209 | } else { 210 | for (String ip_or_group : ip_or_group_array){ 211 | if (FunctionKit.checkStringIsIP(ip_or_group)){ 212 | List result = serverInfoDAO.queryAllFieldByIP(ip_or_group); 213 | if (result.size() != 0){ 214 | objects.addAll(result); 215 | } else { 216 | HelpPrompt.printIpOrGroupNotExists(ip_or_group); 217 | } 218 | } else if (serverInfoDAO.queryAllFieldByServerGroup(ip_or_group).size() != 0) { 219 | objects.addAll(serverInfoDAO.queryAllFieldByServerGroup(ip_or_group)); 220 | } else { 221 | HelpPrompt.printIpOrGroupNotExists(ip_or_group); 222 | check_occur_error = true; 223 | } 224 | } 225 | } 226 | if (! check_occur_error){ 227 | WriteLog writeLog = new WriteLog(); 228 | if ("ssh".equals(ssh_sftp)){ 229 | SessionPool.setSsh_connection_pool(new HashMap()); 230 | ExecCommand.setWriteLog(writeLog); 231 | loopGetCommandFromInteractiveForExec(writeLog,objects); 232 | } else { 233 | SessionPool.setSftp_connection_pool(new HashMap()); 234 | UploadFile.setWriteLog(writeLog); 235 | uploadFileFromInteractive(objects); 236 | } 237 | } 238 | } 239 | } 240 | } 241 | 242 | 243 | /** 244 | * 循环从交互的命令行获取命令用于执行 245 | * @param writeLog 用来写日志的对象 246 | * @param objects ServerInfo对象列表 247 | */ 248 | void loopGetCommandFromInteractiveForExec(WriteLog writeLog,List objects){ 249 | HelpPrompt.printAskExecCommand(); 250 | String command = getInputContent(); 251 | if (! FunctionKit.checkStringLengthIsZero(command)) { 252 | HelpPrompt.printInputError(); 253 | } else if ("q".equals(command) || "Q".equals(command)){ 254 | HelpPrompt.printExitExecCommand(); 255 | HashMap ssh_connection_pool = SessionPool.getSsh_connection_pool(); 256 | if (ssh_connection_pool.size() != 0){ 257 | for (String ip : ssh_connection_pool.keySet()){ 258 | Session session = ssh_connection_pool.get(ip); 259 | if (session.isConnected()){ 260 | session.disconnect(); 261 | } 262 | } 263 | } 264 | ssh_connection_pool.clear(); 265 | } else { 266 | writeLog.writeCommand(command); 267 | 268 | //设置要执行的命令 269 | if (FunctionKit.checkCommandIsForceDeleteRootDirectory(command)){ 270 | HelpPrompt.printYouCanntExecThisCommand(); 271 | } else { 272 | ExecCommand.setCommand(command); 273 | MultiThread multiThread = new MultiThread(); 274 | HashMap ssh_connection_pool = SessionPool.getSsh_connection_pool(); 275 | int ssh_connection_pool_size = ssh_connection_pool.size(); 276 | long start_time = System.currentTimeMillis(); 277 | if (ssh_connection_pool_size == 0){ 278 | multiThread.startMultiThread(objects,"ssh"); //新建会话多线程执行 279 | } else { 280 | multiThread.startMultiThread(ssh_connection_pool); //使用连接池 多线程执行 281 | } 282 | long end_time = System.currentTimeMillis(); 283 | HelpPrompt.printExecuteTime(objects.size(),(end_time - start_time)/1000); 284 | } 285 | 286 | //递归调用自身获取命令执行 287 | loopGetCommandFromInteractiveForExec(writeLog,objects); 288 | } 289 | } 290 | 291 | 292 | /** 293 | * 交互的模式下上传文件 294 | * @param objects ServerInfo对象列表 295 | */ 296 | void uploadFileFromInteractive(List objects){ 297 | HelpPrompt.printFilePath(); 298 | String file_info = getInputContent(); 299 | if (! FunctionKit.checkStringLengthIsZero(file_info)){ 300 | HelpPrompt.printInputError(); 301 | } else { 302 | String[] src_dst = file_info.split("\\s+"); 303 | String file = src_dst[0]; 304 | File src_file = new File(file); 305 | if (src_file.exists() && src_file.isFile() ){ 306 | int src_dst_len = src_dst.length; 307 | if ( src_dst_len == 1){ 308 | MultiThreadUploadFile(file,"/tmp",objects); 309 | } else if (src_dst_len == 2){ 310 | MultiThreadUploadFile(file,src_dst[1],objects); 311 | } else { 312 | HelpPrompt.printParametersTooMany(); 313 | } 314 | } else if (src_file.isDirectory()){ 315 | HelpPrompt.printNotSupportDirectory(); 316 | } else { 317 | HelpPrompt.printSrcFileNotExists(file); 318 | } 319 | } 320 | } 321 | 322 | 323 | /** 324 | * 多线程上传文件 325 | * @param src_file 源文件 326 | * @param remote_path 目标路径 327 | * @param objects ServerInfo对象列表 328 | */ 329 | private void MultiThreadUploadFile(String src_file,String remote_path,List objects){ 330 | UploadFile.setSrc(src_file); 331 | UploadFile.setDst(remote_path); 332 | if (! remote_path.startsWith("/")){ 333 | remote_path = "$HOME/" + remote_path; 334 | } 335 | HelpPrompt.printFileSizeAndRemotePath(src_file,remote_path); 336 | long start_time = System.currentTimeMillis(); 337 | MultiThread multiThread = new MultiThread(); 338 | multiThread.startMultiThread(objects,"sftp"); 339 | long end_time = System.currentTimeMillis(); 340 | System.out.println(); 341 | HelpPrompt.printExecuteTime(objects.size(),(end_time - start_time)/1000); 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /src/org/easyxms/ChoiceNumber.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | class ChoiceNumber { 5 | 6 | 7 | private String cmd = null; 8 | private GetInput getInput = null; 9 | private ServerInfoDAO serverInfoDAO = null; 10 | private ActionForChoiceNumber action = null; 11 | 12 | 13 | ChoiceNumber() { 14 | getInput = new GetInput(); 15 | serverInfoDAO = new ServerInfoDAO(); 16 | action = new ActionForChoiceNumber(); 17 | } 18 | 19 | 20 | /** 21 | * 循环得到输入的命令 22 | */ 23 | public void loopGetValue(){ 24 | HelpPrompt.printWelcomeInfo(); 25 | while (setInputValue()){ 26 | if ("?".equals(cmd) || "?".equals(cmd)){ 27 | HelpPrompt.printPrompt(); 28 | } else if ("1".equals(cmd)){ 29 | action.connectServerForSSHSFTP(serverInfoDAO,"ssh"); 30 | } else if ("2".equals(cmd)){ 31 | action.connectServerForSSHSFTP(serverInfoDAO,"sftp"); 32 | } else if ("3".equals(cmd)){ 33 | action.addServerFromCommandLine(serverInfoDAO); 34 | } else if ("4".equals(cmd)){ 35 | action.addServerFromExcelFile(serverInfoDAO); 36 | } else if ("5".equals(cmd)){ 37 | action.listIPGroupFromDatabase(serverInfoDAO); 38 | } else if ("6".equals(cmd)){ 39 | action.listGroupFromDatabase(serverInfoDAO); 40 | } else if ("7".equals(cmd)){ 41 | action.deleteServerInfoFromDatabase(serverInfoDAO); 42 | } 43 | } 44 | } 45 | 46 | 47 | /** 48 | * 显示提示符等到用户输入 49 | * @return true 50 | */ 51 | public boolean setInputValue(){ 52 | HelpPrompt.printProgramName(); 53 | cmd = getInput.getInputFromStandardInput().trim(); 54 | if ("q".equals(cmd) || "Q".equals(cmd)){ 55 | Quit.quit(); 56 | } 57 | return true; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/org/easyxms/CommandLineAction.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.Session; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * 直接从命令行操作时的动作 12 | */ 13 | public class CommandLineAction { 14 | 15 | HashMap sessionHashMap = new HashMap(); 16 | ServerInfoDAO serverInfoDAO = new ServerInfoDAO(); 17 | 18 | 19 | /** 20 | * 直接从命令行执行命令 21 | * @param objects ServerInfo对象列表 22 | * @param command 要执行的命令 23 | */ 24 | public void commandlineExec(List objects,String command){ 25 | long start_time = System.currentTimeMillis(); 26 | WriteLog writeLog = new WriteLog(); 27 | SessionPool.setSsh_connection_pool(sessionHashMap); 28 | writeLog.writeCommand(command); 29 | ExecCommand.setCommand(command); 30 | ExecCommand.setWriteLog(writeLog); 31 | MultiThread multiThread = new MultiThread(); 32 | multiThread.startMultiThread(objects,"ssh"); 33 | HashMap sessions = SessionPool.getSsh_connection_pool(); 34 | for (Session session : sessions.values()){ 35 | session.disconnect(); 36 | } 37 | sessionHashMap.clear(); 38 | long end_time = System.currentTimeMillis(); 39 | HelpPrompt.printExecuteTime(objects.size(),(end_time - start_time)/1000); 40 | } 41 | 42 | 43 | /** 44 | * 直接从命令行上传文件 45 | * @param src_file 上传的原文件 46 | * @param remote_path 远程服务器的路径 47 | * @param objects ServerInfo对象列表 48 | */ 49 | public void commandlineUploadFile(String src_file,String remote_path,List objects){ 50 | WriteLog writeLog = new WriteLog(); 51 | SessionPool.setSftp_connection_pool(sessionHashMap); 52 | UploadFile.setWriteLog(writeLog); 53 | UploadFile.setSrc(src_file); 54 | UploadFile.setDst(remote_path); 55 | if (! remote_path.startsWith("/")){ 56 | remote_path = "$HOME/" + remote_path; 57 | } 58 | HelpPrompt.printFileSizeAndRemotePath(src_file,remote_path); 59 | long start_time = System.currentTimeMillis(); 60 | MultiThread multiThread = new MultiThread(); 61 | multiThread.startMultiThread(objects,"sftp"); 62 | HashMap sessions = SessionPool.getSftp_connection_pool(); 63 | for (Session session : sessions.values()){ 64 | session.disconnect(); 65 | } 66 | sessionHashMap.clear(); 67 | long end_time = System.currentTimeMillis(); 68 | System.out.println(); 69 | HelpPrompt.printExecuteTime(objects.size(),(end_time - start_time)/1000); 70 | } 71 | 72 | 73 | /** 74 | * 命令行单IP执行命令 75 | * @param ip IP地址 76 | * @param command 要执行的命令 77 | */ 78 | public void ipExecCommand(String ip,String command){ 79 | if (FunctionKit.checkStringIsIP(ip)){ 80 | List objects = serverInfoDAO.queryAllFieldByIP(ip); 81 | if (objects.size() != 0){ 82 | commandlineExec(objects,command); 83 | } else { 84 | HelpPrompt.printIpOrGroupNotExists(ip); 85 | } 86 | } else { 87 | HelpPrompt.printIsNotIP(ip); 88 | } 89 | } 90 | 91 | 92 | /** 93 | * 命令行单IP执行上传文件 94 | * @param ip IP地址 95 | * @param src 上传的源文件 96 | * @param dst 目标地址 97 | */ 98 | public void ipUpload(String ip,String src,String dst){ 99 | if (FunctionKit.checkStringIsIP(ip)){ 100 | if (FunctionKit.checkFileIsExists(src)){ 101 | List objects = serverInfoDAO.queryAllFieldByIP(ip); 102 | if (objects.size() != 0){ 103 | commandlineUploadFile(src, dst, objects); 104 | } else { 105 | HelpPrompt.printIpOrGroupNotExists(ip); 106 | } 107 | } else { 108 | HelpPrompt.printSrcFileNotExists(src); 109 | } 110 | } else { 111 | HelpPrompt.printIsNotIP(ip); 112 | } 113 | } 114 | 115 | 116 | /** 117 | * 命令行 分组执行命令 118 | * @param group 分组 119 | * @param command 执行的命令 120 | */ 121 | public void groupExecCommand(String group,String command){ 122 | List objects = null; 123 | if ("all".equals(group)){ 124 | objects = serverInfoDAO.queryAll(); 125 | } else { 126 | objects = serverInfoDAO.queryAllFieldByServerGroup(group); 127 | } 128 | 129 | if (objects.size() !=0){ 130 | commandlineExec(objects,command); 131 | } else { 132 | HelpPrompt.printIpOrGroupNotExists(group); 133 | } 134 | } 135 | 136 | 137 | /** 138 | * 命令行 分组上传文件 139 | * @param group 分组 140 | * @param src 上传的源文件 141 | * @param dst 目标路径 142 | */ 143 | public void groupUpload(String group,String src,String dst){ 144 | if (FunctionKit.checkFileIsExists(src)){ 145 | List objects = null; 146 | if ("all".equals(group)){ 147 | objects = serverInfoDAO.queryAll(); 148 | } else { 149 | objects = serverInfoDAO.queryAllFieldByServerGroup(group); 150 | } 151 | 152 | if (objects.size() != 0){ 153 | commandlineUploadFile(src, dst, objects); 154 | } else { 155 | HelpPrompt.printIpOrGroupNotExists(group); 156 | } 157 | } else { 158 | HelpPrompt.printSrcFileNotExists(src); 159 | } 160 | } 161 | 162 | 163 | /** 164 | * 命令行 读取文件中的IP信息来执行命令 165 | * @param file 要读取的文件 166 | * @param command 要执行的命令 167 | */ 168 | public void fileExecCommand(String file,String command){ 169 | if (FunctionKit.checkFileIsExists(file)){ 170 | GetIPInfoFromFile getIPInfoFromFile = new GetIPInfoFromExcel(); 171 | List objects = new ArrayList(); 172 | for (Object obj : getIPInfoFromFile.getIPInfo(file)){ 173 | objects.add((ServerInfo)obj); 174 | } 175 | commandlineExec(objects, command); 176 | } else { 177 | HelpPrompt.printSrcFileNotExists(file); 178 | } 179 | } 180 | 181 | 182 | /** 183 | * 命令行 读取文件中的IP信息来上传文件 184 | * @param file 要读取的文件 185 | * @param src 上传的源文件 186 | * @param dst 目标路径 187 | */ 188 | public void fileUpload(String file,String src,String dst){ 189 | if (FunctionKit.checkFileIsExists(file)){ 190 | GetIPInfoFromFile getIPInfoFromFile = new GetIPInfoFromExcel(); 191 | List objects = new ArrayList(); 192 | for (Object obj : getIPInfoFromFile.getIPInfo(file)){ 193 | objects.add((ServerInfo)obj); 194 | } 195 | commandlineUploadFile(src,dst,objects); 196 | } else { 197 | HelpPrompt.printSrcFileNotExists(file); 198 | } 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/org/easyxms/CommandLineOptionsParser.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import org.apache.commons.cli.*; 5 | 6 | 7 | /** 8 | * 解析命令行参数 9 | */ 10 | class CommandLineOptionsParser { 11 | 12 | public static void optionArgsParser(String[] args){ 13 | 14 | CommandLineParser parser = new GnuParser(); 15 | Options options = new Options(); 16 | HelpFormatter formatter = new HelpFormatter(); 17 | 18 | Option help = new Option("h","help",false,"Print Help Info"); 19 | 20 | Option ip = new Option("i","ip",true,"IP Address"); 21 | ip.setArgName("IP Address"); 22 | 23 | Option command = new Option("e","exec",true,"Execute Command"); 24 | command.setArgName("Execute Command"); 25 | 26 | Option group_name = new Option("g","group",true,"Group Name"); 27 | group_name.setArgName("Group Name"); 28 | 29 | Option src_file = new Option("s","src",true,"Source File"); 30 | src_file.setArgName("Source File"); 31 | 32 | Option dst_path = new Option("d","dst",true,"Destination Path"); 33 | dst_path.setArgName("Destination Path"); 34 | 35 | Option excel_file = new Option("f","excel",true,"IP Information Excel File"); 36 | excel_file.setArgName("IP Information Excel File"); 37 | 38 | options.addOption(help); 39 | options.addOption(ip); 40 | options.addOption(command); 41 | options.addOption(group_name); 42 | options.addOption(src_file); 43 | options.addOption(dst_path); 44 | options.addOption(excel_file); 45 | 46 | String usage = "-i IP -e COMMAND\n" + 47 | "-i IP -s /local/path/to/file -d /remote/path/to/file\n" + 48 | "-g GROUP_NAME -e COMMAND\n" + 49 | "-g GROUP_NAME -s /local/path/to/file -d /remote/path/to/file\n" + 50 | "-f EXCEL_FILE -e COMMAND\n" + 51 | "-f EXCEL_FILE -s /local/path/to/file -d /remote/path/to/file\n"; 52 | String footer = "\nEasyXMS 2015-02-03 www.linux178.com 58@linux178.com"; 53 | 54 | try { 55 | CommandLine cmd_line = parser.parse(options,args); 56 | CommandLineAction commandLineAction = new CommandLineAction(); 57 | if (cmd_line.hasOption("i") && cmd_line.hasOption("e")){ 58 | String i_value = cmd_line.getOptionValue("i"); 59 | String e_value = cmd_line.getOptionValue("e"); 60 | commandLineAction.ipExecCommand(i_value,e_value); 61 | } else if (cmd_line.hasOption("i") && cmd_line.hasOption("s") && cmd_line.hasOption("d")){ 62 | String i_value = cmd_line.getOptionValue("i"); 63 | String s_value = cmd_line.getOptionValue("s"); 64 | String d_value = cmd_line.getOptionValue("d"); 65 | commandLineAction.ipUpload(i_value,s_value,d_value); 66 | } else if (cmd_line.hasOption("g") && cmd_line.hasOption("e")){ 67 | String g_value = cmd_line.getOptionValue("g"); 68 | String e_value = cmd_line.getOptionValue("e"); 69 | commandLineAction.groupExecCommand(g_value,e_value); 70 | } else if (cmd_line.hasOption("g") && cmd_line.hasOption("s") && cmd_line.hasOption("d")){ 71 | String g_value = cmd_line.getOptionValue("g"); 72 | String s_value = cmd_line.getOptionValue("s"); 73 | String d_value = cmd_line.getOptionValue("d"); 74 | commandLineAction.groupUpload(g_value,s_value,d_value); 75 | } else if (cmd_line.hasOption("f") && cmd_line.hasOption("e")){ 76 | String f_value = cmd_line.getOptionValue("f"); 77 | String e_value = cmd_line.getOptionValue("e"); 78 | commandLineAction.fileExecCommand(f_value,e_value); 79 | } else if (cmd_line.hasOption("f") && cmd_line.hasOption("s") && cmd_line.hasOption("d")){ 80 | String f_value = cmd_line.getOptionValue("f"); 81 | String s_value = cmd_line.getOptionValue("s"); 82 | String d_value = cmd_line.getOptionValue("d"); 83 | commandLineAction.fileUpload(f_value,s_value,d_value); 84 | } else { 85 | formatter.printHelp("start.(sh|bat) [OPTIONS]",usage+"Options:",options,footer); 86 | } 87 | } catch (ParseException e) { 88 | HelpPrompt.printInfo("Parsing failed.Reason: " + e.getMessage()); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/org/easyxms/ConnectServer.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.*; 5 | 6 | 7 | class ConnectServer{ 8 | 9 | 10 | /** 11 | * 连接服务器打开会话 12 | * @return 连接会话对象 13 | */ 14 | public Session connectServerOpenSession(ServerInfo serverInfo,WriteLog writeLog){ 15 | JSch jSch = new JSch(); 16 | Session session = null; 17 | String ip = serverInfo.getIp(); 18 | try { 19 | session = jSch.getSession(EncryptDecryptPassword.Decrypt(serverInfo.getUsername()),ip,serverInfo.getPort()); 20 | session.setConfig("StrictHostKeyChecking", "no"); 21 | session.setConfig("userauth.gssapi-with-mic", "no"); 22 | session.setTimeout(SettingInfo.getConnect_timeout()); 23 | session.setPassword(EncryptDecryptPassword.Decrypt(serverInfo.getPassword())); 24 | if (SettingInfo.getEnable_http_proxy() == 1){ 25 | session.setProxy(new ProxyHTTP(SettingInfo.getHttp_proxy_server(),SettingInfo.getHttp_proxy_port())); 26 | } 27 | session.connect(); 28 | } catch (JSchException e){ 29 | writeLog.writeCommandResult("\n" + HelpPrompt.printConnectError(ip,e.getMessage()) + "\n"); 30 | } 31 | return session; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/org/easyxms/DBManager.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.sql.*; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * 用来执行连接数据库、插入、查询、删除操作 11 | */ 12 | class DBManager { 13 | 14 | 15 | /** 16 | * 获得数据库连接 17 | * @return 连接对象 18 | */ 19 | Connection getConnection(){ 20 | Connection conn = null; 21 | try { 22 | Class.forName("org.sqlite.JDBC"); 23 | conn = DriverManager.getConnection("jdbc:sqlite:conf/easyxms.db"); 24 | } catch (ClassNotFoundException e){ 25 | System.out.println(e.getMessage()); 26 | } catch (SQLException e){ 27 | System.out.println(e.getMessage()); 28 | } 29 | return conn; 30 | } 31 | 32 | 33 | /** 34 | * 创建表 35 | * @param create_table_sql 创建表语句 36 | */ 37 | void create(String create_table_sql){ 38 | Connection conn = this.getConnection(); 39 | PreparedStatement psta = null; 40 | try { 41 | if (conn != null){ 42 | psta = conn.prepareStatement(create_table_sql); 43 | psta.executeUpdate(); 44 | } 45 | } catch (SQLException e){ 46 | System.out.println(e.getMessage()); 47 | } finally { 48 | this.close(psta,conn); 49 | } 50 | } 51 | 52 | 53 | /** 54 | * 用来执行 insert 语句,并返回影响的行数 55 | * @param update_sql 要执行的插入,删除SQL语句 56 | * @param objects 是ServerInfo对象 57 | * @param query_sql 查询的某个IP或者组的SQL语句 58 | * @return 返回影响的行数 59 | * 60 | * */ 61 | int[] insert(String update_sql,List objects,String query_sql){ 62 | Connection conn = this.getConnection(); 63 | PreparedStatement psta = null; 64 | int[] rows = new int[0]; 65 | try { 66 | if (conn != null){ 67 | psta = conn.prepareStatement(update_sql); 68 | for (Object obj : objects){ 69 | String ip = ((ServerInfo) obj).getIp(); 70 | if (query(query_sql,ip)){ 71 | HelpPrompt.printIPAlreadyExists(ip); 72 | } else { 73 | psta.setObject(1,ip); 74 | psta.setObject(2,((ServerInfo) obj).getServer_group()); 75 | psta.setObject(3,((ServerInfo) obj).getUsername()); 76 | psta.setObject(4,((ServerInfo) obj).getPassword()); 77 | psta.setObject(5,((ServerInfo) obj).getPort()); 78 | psta.addBatch(); 79 | HelpPrompt.printAddServerSuccess(ip); 80 | } 81 | } 82 | rows = psta.executeBatch(); 83 | } 84 | } catch (SQLException e){ 85 | System.out.println(e.getMessage()); 86 | } finally { 87 | this.close(psta,conn); 88 | } 89 | return rows; 90 | } 91 | 92 | 93 | /** 94 | * 删除操作 95 | * @param delete_sql 删除的SQL语句 96 | * @param args 删除语句的参数 97 | * @param query_sql 查询语句,删除之前需要查询是否存在 98 | * @return 返回一个影响的行数的数组 99 | */ 100 | int[] delete(String delete_sql,List args,String query_sql){ 101 | int[] rows = new int[0]; 102 | Connection conn = this.getConnection(); 103 | PreparedStatement psta = null; 104 | try { 105 | if (conn != null){ 106 | psta = conn.prepareStatement(delete_sql); 107 | String isIPorGroup = args.get(0); 108 | if (query(query_sql,isIPorGroup)){ 109 | psta.setObject(1,isIPorGroup); 110 | psta.executeUpdate(); 111 | HelpPrompt.printDeleteServerInfoSucessful(isIPorGroup); 112 | } else { 113 | HelpPrompt.printIpOrGroupNotExists(isIPorGroup); 114 | } 115 | } 116 | } catch (SQLException e){ 117 | System.out.println(e.getMessage()); 118 | } finally { 119 | this.close(psta,conn); 120 | } 121 | return rows; 122 | } 123 | 124 | 125 | /** 126 | * 清空表 127 | * @param delete_all_sql 清空表的SQL语句 128 | * @return 影响的行数 129 | */ 130 | int delete(String delete_all_sql){ 131 | int rows = 0; 132 | Connection conn = this.getConnection(); 133 | PreparedStatement psta = null; 134 | try { 135 | psta = conn.prepareStatement(delete_all_sql); 136 | rows = psta.executeUpdate(); 137 | HelpPrompt.printClearTableSucessful(); 138 | } catch (SQLException e){ 139 | System.out.println(e.getMessage()); 140 | } finally { 141 | this.close(psta,conn); 142 | } 143 | return rows; 144 | } 145 | 146 | 147 | /** 148 | * 用来执行select语句并返回true false,用来查询ip或者server_group是否存在 149 | * @param sql 要执行的SQL语句 150 | * @param ip_group 要查询的是ip或者是server_group 151 | * @return 如果ip或者是server_group存在则返回true,否则返回false 152 | */ 153 | boolean query(String sql,String ip_group){ 154 | Connection conn = this.getConnection(); 155 | PreparedStatement psta = null; 156 | ResultSet rs = null; 157 | try { 158 | if (conn != null){ 159 | psta = conn.prepareStatement(sql); 160 | psta.setString(1,ip_group); 161 | rs = psta.executeQuery(); 162 | if (rs.next()){ 163 | return true; 164 | } 165 | } 166 | } catch (SQLException e){ 167 | System.out.println(e.getMessage()); 168 | } finally { 169 | this.close(rs,psta,conn); 170 | } 171 | return false; 172 | } 173 | 174 | 175 | /** 176 | * 用来执行 select 语句,并返回一个实体对象List 177 | * @param sql 要执行的SQL语句 178 | * @param args 构造SQL语句的字段集合 179 | * @param mapping ResultSet转换为实体类的接口对象 180 | * @return 返回一个List 181 | * 182 | * */ 183 | List query(String sql,List args,ResultSetToEntityMapping mapping){ 184 | Connection conn = this.getConnection(); 185 | List serverinfo_objs = new ArrayList(); 186 | PreparedStatement psta = null; 187 | ResultSet rs = null; 188 | try { 189 | if (conn != null){ 190 | psta = conn.prepareStatement(sql); 191 | for (int i = 0; i < args.size(); i++) { 192 | psta.setObject(i+1,args.get(i)); 193 | } 194 | rs = psta.executeQuery(); 195 | while (rs.next()){ 196 | serverinfo_objs.add((ServerInfo)mapping.mapping(rs)); 197 | } 198 | } 199 | }catch (SQLException e){ 200 | System.out.println(e.getMessage()); 201 | } finally { 202 | this.close(rs,psta,conn); 203 | } 204 | return serverinfo_objs; 205 | } 206 | 207 | 208 | /** 209 | * 用来执行 select 语句,并返回一个String List 210 | * @param sql 要执行的SQL语句 211 | * @param args SQL语句的参数 212 | * @param identifier 用来标识sql语句想要获得的列名 213 | * @return 返回一个String List 214 | */ 215 | List query(String sql,List args,String identifier){ 216 | Connection conn = this.getConnection(); 217 | PreparedStatement psta = null; 218 | ResultSet rs = null; 219 | List result_list = new ArrayList(); 220 | StringBuilder str = new StringBuilder(""); 221 | try { 222 | if (conn != null){ 223 | psta = conn.prepareStatement(sql); 224 | for (int i = 0; i < args.size(); i++) { 225 | psta.setObject(i+1,args.get(i)); 226 | } 227 | rs = psta.executeQuery(); 228 | if ("ip_group".equals(identifier)){ 229 | while (rs.next()){ 230 | str.append(rs.getString("ip")); 231 | str.append(" "); 232 | str.append(rs.getString("server_group")); 233 | result_list.add(str.toString()); 234 | str.setLength(0); 235 | } 236 | } else if ("ip_group_bygroup".equals(identifier)){ 237 | while (rs.next()){ 238 | str.append(rs.getString("ip")); 239 | str.append(" "); 240 | str.append(rs.getString("server_group")); 241 | result_list.add(str.toString()); 242 | str.setLength(0); 243 | } 244 | } else if ("group".equals(identifier)){ 245 | while (rs.next()){ 246 | result_list.add(rs.getString("server_group")); 247 | } 248 | } 249 | } 250 | } catch (SQLException e){ 251 | System.out.println(e.getMessage()); 252 | } finally { 253 | this.close(rs,psta,conn); 254 | } 255 | return result_list; 256 | } 257 | 258 | 259 | /** 260 | * 关闭函数 261 | * 262 | * */ 263 | void close(ResultSet rs,PreparedStatement psta,Connection conn){ 264 | try { 265 | if (rs !=null){ 266 | rs.close(); 267 | } 268 | if (psta !=null){ 269 | psta.close(); 270 | } 271 | if (conn != null){ 272 | conn.close(); 273 | } 274 | } catch (SQLException e){ 275 | System.out.println(e.getMessage()); 276 | } 277 | } 278 | 279 | 280 | /** 281 | * 关闭函数 282 | * 283 | * */ 284 | void close(PreparedStatement psta,Connection conn){ 285 | try { 286 | if (psta !=null){ 287 | psta.close(); 288 | } 289 | if (conn != null){ 290 | conn.close(); 291 | } 292 | } catch (SQLException e){ 293 | System.out.println(e.getMessage()); 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/org/easyxms/EasyXMS.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | public class EasyXMS { 5 | 6 | public static void main(String[] args){ 7 | 8 | if (args.length != 0){ 9 | CommandLineOptionsParser.optionArgsParser(args); 10 | } else { 11 | //读取配置文件并设置 12 | SettingInfo.settingInfo(); 13 | 14 | //开始执行 15 | ChoiceNumber choiceNumber = new ChoiceNumber(); 16 | choiceNumber.loopGetValue(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/org/easyxms/EncryptDecryptPassword.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import it.sauronsoftware.base64.*; 5 | 6 | 7 | /** 8 | * 加密解密类 9 | */ 10 | class EncryptDecryptPassword { 11 | 12 | 13 | /** 14 | * 加密字符串 15 | * @param password 要加密的字符串 16 | * @return 加密后的字符串 17 | */ 18 | static String Encrypt(String password){ 19 | return Base64.encode(password); 20 | } 21 | 22 | 23 | /** 24 | * 解密字符串 25 | * @param encrypt_password 加密过的字符串 26 | * @return 解密后的字符串 27 | */ 28 | static String Decrypt(String encrypt_password){ 29 | return Base64.decode(encrypt_password); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/org/easyxms/ExecCommand.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.ChannelExec; 5 | import com.jcraft.jsch.JSchException; 6 | import com.jcraft.jsch.Session; 7 | import java.io.BufferedReader; 8 | import java.io.IOException; 9 | import java.io.InputStreamReader; 10 | import java.util.concurrent.CountDownLatch; 11 | 12 | 13 | /** 14 | * 执行命令类 继承ConnectServer类 实现Runnable接口 15 | */ 16 | class ExecCommand extends ConnectServer implements Runnable{ 17 | 18 | private static String command = null; 19 | private String ip = null; 20 | private static CountDownLatch countDownLatch = null; 21 | private Session session = null; 22 | private static int is_use_session_pool = 0; //是否使用session会话池 23 | private static WriteLog writeLog = null; 24 | private ServerInfo serverInfo = null; 25 | 26 | ExecCommand(String ip,Session session) { 27 | this.ip = ip; 28 | this.session = session; 29 | } 30 | 31 | ExecCommand(ServerInfo serverInfo) { 32 | this.serverInfo = serverInfo; 33 | this.ip = serverInfo.getIp(); 34 | } 35 | 36 | @Override 37 | public void run() { 38 | if (is_use_session_pool == 0){ 39 | openExecCommandChannel(); 40 | } else { 41 | execCommandGetResult(session); 42 | } 43 | countDownLatch.countDown(); 44 | } 45 | 46 | public static void setWriteLog(WriteLog writeLog) { 47 | ExecCommand.writeLog = writeLog; 48 | } 49 | 50 | public static void setIs_use_session_pool(int is_use_session_pool) { 51 | ExecCommand.is_use_session_pool = is_use_session_pool; 52 | } 53 | 54 | 55 | //设置子线程同步计数器 56 | public static void setCountDownLatch(CountDownLatch count_down) { 57 | countDownLatch = count_down; 58 | } 59 | 60 | 61 | //设置要执行的命令 62 | public static void setCommand(String command) { 63 | ExecCommand.command = command; 64 | } 65 | 66 | 67 | /** 68 | * 打开执行命令通道 69 | */ 70 | public void openExecCommandChannel(){ 71 | Session session = connectServerOpenSession(serverInfo,writeLog); 72 | if (session.isConnected()){ 73 | //把session会话放到 session连接池中,以备下一次使用 74 | SessionPool.getSsh_connection_pool().put(ip,session); 75 | execCommandGetResult(session); 76 | } 77 | } 78 | 79 | 80 | /** 81 | * 执行命令得到结果 82 | * @param session 连接之后形成的会话 83 | */ 84 | public void execCommandGetResult(Session session){ 85 | StringBuilder result = new StringBuilder(); 86 | result.append(String.format("======== [ %s ] execute Command: ' %s ', The Result is:\n",ip,command)); 87 | try { 88 | ChannelExec channelExec = (ChannelExec)session.openChannel("exec"); 89 | channelExec.setEnv("LC_MESSAGES","en_US.UTF-8"); 90 | channelExec.setCommand(command); 91 | BufferedReader exec_result = new BufferedReader(new InputStreamReader(channelExec.getInputStream())); 92 | BufferedReader error_result = new BufferedReader(new InputStreamReader(channelExec.getErrStream())); 93 | channelExec.connect(); 94 | Thread.sleep(SettingInfo.getSleep_time()); 95 | int result_start = result.length(); 96 | 97 | //得到标准输出 98 | while (exec_result.ready()){ 99 | result.append(exec_result.readLine()); 100 | result.append("\n"); 101 | } 102 | 103 | //得到标准错误输出 104 | while (error_result.ready()){ 105 | result.append(error_result.readLine()); 106 | result.append("\n"); 107 | } 108 | 109 | int result_stop = result.length(); 110 | if (result_stop == result_start){ 111 | if (channelExec.getExitStatus() == 0){ 112 | result.append("Command execute ... OK\n"); 113 | } else { 114 | result.append("aOo,Not get results,Please Try Again!\n"); 115 | } 116 | } 117 | 118 | String result_string = result.toString(); 119 | writeLog.writeCommandResult(result_string); 120 | HelpPrompt.printInfo(result_string); 121 | 122 | } catch (IOException e){ 123 | HelpPrompt.printInfo(e.getMessage()); 124 | } catch (InterruptedException e){ 125 | HelpPrompt.printInfo(e.getMessage()); 126 | } catch (JSchException e){ 127 | HelpPrompt.printInfo(e.getMessage()); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/org/easyxms/FileTransferProgressMonitor.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.SftpProgressMonitor; 5 | 6 | 7 | class FileTransferProgressMonitor implements SftpProgressMonitor{ 8 | 9 | private static String str = "|/-\\"; 10 | 11 | 12 | /** 13 | * 传输开始的时候执行 14 | * @param op 标识是GET还是PUT 15 | * @param src 源 16 | * @param dst 目标 17 | * @param file_length 文件的大小 18 | */ 19 | @Override 20 | public void init(int op, String src, String dst, long file_length) {} 21 | 22 | 23 | /** 24 | * 到目前为止已经传输了多少字节 25 | * @param count 目前已经传输了多少字节 26 | * @return true 27 | */ 28 | @Override 29 | public boolean count(long count) { 30 | System.out.printf("\rAll Servers are Transferring,Please Wait moment ... %s", 31 | str.charAt((int)(Math.random()*str.length()))); 32 | return true; 33 | } 34 | 35 | 36 | /** 37 | * 传输结束的时候执行 38 | */ 39 | @Override 40 | public void end() {} 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/easyxms/FunctionKit.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.io.File; 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | 10 | 11 | /** 12 | * 功能函数类 13 | */ 14 | class FunctionKit { 15 | 16 | 17 | /** 18 | * 检测输入的内容是否为IP地址 19 | * @param ip IP地址 20 | * @return 是否为IP地址 21 | */ 22 | public static boolean checkStringIsIP(String ip){ 23 | String pattern = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}"; 24 | Pattern ip_pattern = Pattern.compile(pattern); 25 | Matcher ip_matcher = ip_pattern.matcher(ip); 26 | return ip_matcher.matches(); 27 | } 28 | 29 | 30 | /** 31 | * 检查输入的字符串长度是否为0,为0则表示没有输入 32 | * @param string 输入的字符串 33 | * @return 长度是否为0,也即是不是输入了字符串 34 | */ 35 | public static boolean checkStringLengthIsZero(String string){ 36 | boolean is_not_zero = true; 37 | if (string.trim().length() == 0){ 38 | is_not_zero = false; 39 | } 40 | return is_not_zero; 41 | } 42 | 43 | 44 | /** 45 | * 检查输入的命令是否是 rm -rf / 46 | * @param command 输入的命令 47 | * @return 是否是 rm -rf / 48 | */ 49 | public static boolean checkCommandIsForceDeleteRootDirectory(String command){ 50 | Pattern rm_pattern = Pattern.compile("\\s*rm\\s+-rf\\s+/\\s*"); 51 | Matcher rm_match = rm_pattern.matcher(command); 52 | return rm_match.matches(); 53 | } 54 | 55 | 56 | /** 57 | * 重复某个字符串 58 | * @param string 一个字符串 59 | * @param repeatCount 重复的次数 60 | * @return 重复后的字符串 61 | */ 62 | public static String repeatString(String string, int repeatCount) { 63 | StringBuilder sb = new StringBuilder(string.length() * repeatCount); 64 | for(int i = 0; i < repeatCount; i++) { 65 | sb.append(string); 66 | } 67 | return sb.toString(); 68 | } 69 | 70 | 71 | /** 72 | * 获取日期时间 73 | * 需要传入想要的日期格式,像下面的格式: 74 | * @param dateformat 想要的日期格式 比如:yyyy-MM-dd HH:mm:ss yyyy-MM-dd 75 | * @return 一个日期 76 | * */ 77 | public static String getDate(String dateformat){ 78 | SimpleDateFormat dateFormat = new SimpleDateFormat(dateformat); 79 | return dateFormat.format(new Date()); 80 | } 81 | 82 | 83 | /** 84 | * 如果目录不存在则创建 85 | * @param dirname 创建目录的名称 86 | * @return true 已经创建目录 false 没有创建目录 87 | */ 88 | public static boolean createDirectoryIfNotExist(String dirname){ 89 | File dir = new File(dirname); 90 | return dir.mkdir(); 91 | } 92 | 93 | 94 | /** 95 | * 检测文件是否存在 96 | * @param filename 文件名称字符串 97 | * @return 文件是否存在 98 | */ 99 | public static boolean checkFileIsExists(String filename){ 100 | File file = new File(filename); 101 | return file.exists(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/org/easyxms/GetIPInfoFromExcel.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import jxl.Sheet; 5 | import jxl.Workbook; 6 | import jxl.read.biff.BiffException; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | 13 | class GetIPInfoFromExcel extends GetIPInfoFromFile{ 14 | 15 | 16 | /** 17 | * 从Excel文件中得到IP信息 18 | * @param excel_file 存放IP信息的Excel文件 19 | * @return 一个对象列表 20 | */ 21 | @Override 22 | List getIPInfo(String excel_file) { 23 | List objects = new ArrayList(); 24 | ArrayList host_info = new ArrayList(); 25 | try { 26 | Workbook ip_info = Workbook.getWorkbook(new File(excel_file)); 27 | Sheet first_sheet = ip_info.getSheet(0); 28 | int total_rows = first_sheet.getRows() - 1; 29 | int total_columns = first_sheet.getColumns() - 1; 30 | 31 | for (int i = 1; i <= total_rows ; i++) { 32 | for (int j = 0; j <= total_columns; j++) { 33 | String cell_content = first_sheet.getCell(j, i).getContents(); 34 | host_info.add(cell_content); 35 | } 36 | ServerInfo serverInfo = new ServerInfo(host_info.get(0),host_info.get(1), 37 | EncryptDecryptPassword.Encrypt(host_info.get(2)), 38 | EncryptDecryptPassword.Encrypt(host_info.get(3)), 39 | Integer.parseInt(host_info.get(4))); 40 | objects.add(serverInfo); 41 | host_info.clear(); 42 | } 43 | } catch (IOException e){ 44 | HelpPrompt.printInfo(e.getMessage()); 45 | } catch (BiffException e){ 46 | HelpPrompt.printInfo(e.getMessage()); 47 | } 48 | return objects; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/org/easyxms/GetIPInfoFromFile.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | 5 | import java.util.List; 6 | 7 | 8 | /** 9 | * 抽象类 从文件中获取IP信息 10 | */ 11 | abstract class GetIPInfoFromFile { 12 | abstract List getIPInfo(String file); 13 | } 14 | -------------------------------------------------------------------------------- /src/org/easyxms/GetInput.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.io.BufferedReader; 5 | import java.io.IOException; 6 | import java.io.InputStreamReader; 7 | 8 | 9 | class GetInput { 10 | 11 | /** 12 | * 得到从命令行输入的字符串 13 | * @return 得到的字符串 14 | */ 15 | public String getInputFromStandardInput(){ 16 | String input = null; 17 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 18 | try { 19 | input = br.readLine(); 20 | } catch (IOException e){ 21 | HelpPrompt.printInfo(e.getMessage()); 22 | } 23 | return input; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/org/easyxms/HelpPrompt.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.io.File; 5 | 6 | /** 7 | * 打印信息类 8 | */ 9 | class HelpPrompt { 10 | 11 | private static String command_prompt[] = {"1 Execute Command", 12 | "2 Upload File", 13 | "3 Add Server From < Command Line >", 14 | "4 Add Server From < Excel File >", 15 | "5 List Servers From Database", 16 | "6 List Groups From Database", 17 | "7 Delete Server From Database", 18 | }; 19 | 20 | 21 | private static String program_name = "EasyXMS"; 22 | private static String program_prompt = String.format("%s (? Help | q/Q Quit) >>> ",program_name); 23 | private static String welcome_prompt = String.format("" + 24 | "Welcome to Use < %s > , Please Enter < ? > Get Help or < q/Q > Quit",program_name); 25 | 26 | 27 | /** 28 | * 显示命令帮助 29 | */ 30 | public static void printPrompt(){ 31 | System.out.println(); 32 | for (String i : command_prompt){ 33 | System.out.printf("\t%s\n",i); 34 | } 35 | System.out.println(); 36 | } 37 | 38 | 39 | /** 40 | * 显示程序名称及提示 41 | */ 42 | public static void printProgramName(){ 43 | System.out.print(program_prompt); 44 | } 45 | 46 | 47 | /** 48 | * 显示欢迎信息 49 | */ 50 | public static void printWelcomeInfo(){ 51 | int welcome_len = welcome_prompt.length(); 52 | String henggang_num = FunctionKit.repeatString("-",welcome_len); 53 | System.out.println(henggang_num); 54 | System.out.println(welcome_prompt); 55 | System.out.println(henggang_num); 56 | } 57 | 58 | 59 | /** 60 | * 询问是否退出 61 | */ 62 | public static void printAskQuit(){ 63 | System.out.print("Are you sure Quit ([y]/n): "); 64 | } 65 | 66 | 67 | /** 68 | * 显示输入错误 69 | */ 70 | public static void printInputError(){ 71 | System.out.println("Input Error!"); 72 | } 73 | 74 | 75 | /** 76 | * 显示增加服务器提示 77 | */ 78 | public static void printAddServer(){ 79 | System.out.print("e.g. 1.1.1.1 web root 123 22;2.2.2.2 db root 123 22\n>>>>>"); 80 | } 81 | 82 | 83 | /** 84 | * 提示输入Excel文件的路径 85 | */ 86 | public static void printExcelFilePath(){ 87 | System.out.print("Enter Excel File Path: "); 88 | } 89 | 90 | 91 | /** 92 | * 显示增加服务器成功 93 | * @param ip IP地址 94 | */ 95 | public static void printAddServerSuccess(String ip){ 96 | System.out.printf("[ %s ] Add ... OK\n", ip); 97 | } 98 | 99 | 100 | /** 101 | * 显示IP信息已经存在 102 | * @param ip IP地址 103 | */ 104 | public static void printIPAlreadyExists(String ip){ 105 | System.out.printf("[ %s ] Already Exists\n", ip); 106 | } 107 | 108 | 109 | /** 110 | * 显示列出服务器信息提示 111 | */ 112 | public static void printListServer(){ 113 | System.out.print("Choice List Server ( all|group_name ): "); 114 | } 115 | 116 | 117 | /** 118 | * 显示数据库中没有数据 用于在列出信息时 119 | */ 120 | public static void printNoDataInDataBase(){ 121 | System.out.println("Oops,No Server in Database!!!"); 122 | } 123 | 124 | 125 | /** 126 | * 显示输入要删除的IP信息 127 | */ 128 | public static void printSpecifyIPOrGroupOrAllForDelete(){ 129 | System.out.print("Enter ( all|ip|group ) For Delete :"); 130 | } 131 | 132 | 133 | /** 134 | * 显示IP不在数据库中 用于在删除信息 135 | * @param ip_or_group IP或者分组 136 | */ 137 | public static void printIpOrGroupNotExists(String ip_or_group){ 138 | System.out.printf("[ %s ] Not Exists\n", ip_or_group); 139 | } 140 | 141 | 142 | /** 143 | * 显示删除IP或分组成功 144 | * @param ip_or_group IP或者分组 145 | */ 146 | public static void printDeleteServerInfoSucessful(String ip_or_group){ 147 | System.out.printf("[ %s ] Delete ... OK\n", ip_or_group); 148 | } 149 | 150 | 151 | /** 152 | * 询问是否真的要清空整个表 153 | */ 154 | public static void printAskClearTable(){ 155 | System.out.print("Clear All Server (y/n) :"); 156 | } 157 | 158 | 159 | /** 160 | * 显示清空表成功 161 | */ 162 | public static void printClearTableSucessful(){ 163 | System.out.println("Clear All Server ... OK"); 164 | } 165 | 166 | 167 | /** 168 | * 显示什么也没发生 清空表的时候,选择n或者其他键(除y|Y之外) 169 | */ 170 | public static void printNothingHappen(){ 171 | System.out.println("Nothing Happen!!!"); 172 | } 173 | 174 | 175 | /** 176 | * 显示请输入命令 177 | */ 178 | public static void printAskExecCommand(){ 179 | System.out.print("Enter Command Like 'df -hP' (q/Q Quit) :"); 180 | } 181 | 182 | 183 | /** 184 | * 输出 选择 要执行命令的IP,分组,所有主机 185 | */ 186 | public static void printListIPOrGroupOrAllForExec(){ 187 | System.out.print("Enter ( all|ip|group ) For ssh or sftp :"); 188 | } 189 | 190 | 191 | /** 192 | * 显示退出执行命令 193 | */ 194 | public static void printExitExecCommand(){ 195 | System.out.println("Exit Exec Command!!"); 196 | } 197 | 198 | 199 | /** 200 | * 显示不能执行此命令 201 | */ 202 | public static void printYouCanntExecThisCommand(){ 203 | System.out.println("You Can't Exec This Command"); 204 | } 205 | 206 | 207 | /** 208 | * 显示该IP session 已经断开 209 | * @param ip IP地址 210 | */ 211 | public static void printIPSessionAlreadyDisconnect(String ip){ 212 | System.out.println(String.format("Session < %s > is already disconnected!!!",ip)); 213 | } 214 | 215 | 216 | /** 217 | * 显示信息(出错信息、命令执行的结果) 218 | * @param string 要打印的字符串 219 | */ 220 | public static void printInfo(String string){ 221 | System.out.println(string); 222 | } 223 | 224 | 225 | /** 226 | * 显示连接错误信息 227 | * @param ip IP地址 228 | * @param message 出错的信息 229 | * @return 一个格式化好的字符串 230 | */ 231 | public static String printConnectError(String ip,String message){ 232 | String info = String.format("[ %s ] ... Connect Failue,Cause --> %s ",ip,message); 233 | int info_len = info.length(); 234 | String star_num = FunctionKit.repeatString("*",info_len); 235 | System.out.println(star_num); 236 | System.out.println(info); 237 | System.out.println(star_num); 238 | System.out.println(); 239 | return String.format("%s\n%s\n%s",star_num,info,star_num); 240 | } 241 | 242 | 243 | /** 244 | * 显示输入文件路径 245 | */ 246 | public static void printFilePath(){ 247 | System.out.print("Enter File Path and dir :"); 248 | } 249 | 250 | 251 | 252 | /** 253 | * 显示命令或者上传文件所花费的时间 254 | * @param nums 服务器的数量 255 | * @param time 命令或者上传文件所花费的时间 256 | */ 257 | public static void printExecuteTime(int nums,long time){ 258 | System.out.printf("Servers Number: %d ,Execute Time: %ds\n",nums,time); 259 | } 260 | 261 | 262 | /** 263 | * 在上传文件是显示文件大小及远程路径 264 | * @param src_file 源文件 265 | * @param remote_path 目标路径 266 | */ 267 | public static void printFileSizeAndRemotePath(String src_file,String remote_path){ 268 | System.out.printf("File Size: %d B,Remote Path: %s\n", (new File(src_file)).length(),remote_path); 269 | } 270 | 271 | 272 | /** 273 | * 显示不支持上传目录 274 | */ 275 | public static void printNotSupportDirectory(){ 276 | System.out.println("Oops.Not Support Directory!"); 277 | } 278 | 279 | 280 | /** 281 | * 显示要上传文件不存在 282 | * @param src_file 要上传的文件 283 | */ 284 | public static void printSrcFileNotExists(String src_file){ 285 | System.out.printf("aOo. [ %s ] Not Exists.\n",src_file); 286 | } 287 | 288 | 289 | /** 290 | * 显示参数过多 291 | */ 292 | public static void printParametersTooMany(){ 293 | System.out.println("Parameters Too Many!!!"); 294 | } 295 | 296 | 297 | /** 298 | * 显示不是IP地址 299 | * @param ip IP地址 300 | */ 301 | public static void printIsNotIP(String ip){ 302 | System.out.printf("aOo. [ %s ] Not Exists.\n",ip); 303 | } 304 | 305 | } 306 | -------------------------------------------------------------------------------- /src/org/easyxms/MultiThread.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.concurrent.CountDownLatch; 9 | import com.jcraft.jsch.Session; 10 | 11 | 12 | /** 13 | * 多线程类 14 | */ 15 | class MultiThread{ 16 | 17 | 18 | /** 19 | * 新建会话开始多线程 20 | * @param objects ServerInfo对象列表 21 | */ 22 | public void startMultiThread(List objects,String ssh_sftp){ 23 | 24 | CountDownLatch wait_thread_run_end = new CountDownLatch(objects.size()); 25 | ArrayList threadArrayList = new ArrayList(); //初始化用于存放线程的列表 26 | if ("ssh".equals(ssh_sftp)){ 27 | ExecCommand.setCountDownLatch(wait_thread_run_end); //设置线程同步计数器的数目 28 | ExecCommand.setIs_use_session_pool(0); 29 | for (ServerInfo serverInfo : objects){ 30 | threadArrayList.add(new Thread(new ExecCommand(serverInfo))); 31 | } 32 | } else { 33 | UploadFile.setCountDownLatch(wait_thread_run_end); 34 | UploadFile.setIs_use_session_pool(0); 35 | for (ServerInfo serverInfo : objects){ 36 | threadArrayList.add(new Thread(new UploadFile(serverInfo))); 37 | } 38 | } 39 | threadControl(threadArrayList,wait_thread_run_end); 40 | } 41 | 42 | 43 | /** 44 | * 使用已经连接的会话开始多线程 45 | * @param session_pool 会话池 46 | */ 47 | public void startMultiThread(HashMap session_pool){ 48 | 49 | int host_num = session_pool.size(); 50 | CountDownLatch wait_thread_run_end = new CountDownLatch(host_num); 51 | ExecCommand.setCountDownLatch(wait_thread_run_end); //设置线程同步计数器的数目 52 | 53 | //初始化用于存放线程的列表 54 | ArrayList threadArrayList = new ArrayList(); 55 | ExecCommand.setIs_use_session_pool(1); 56 | for (String ip : session_pool.keySet()){ 57 | Session session = session_pool.get(ip); 58 | if (session.isConnected()){ 59 | threadArrayList.add(new Thread(new ExecCommand(ip,session))); 60 | } else { 61 | HelpPrompt.printIPSessionAlreadyDisconnect(ip); 62 | } 63 | } 64 | threadControl(threadArrayList, wait_thread_run_end); 65 | } 66 | 67 | 68 | /** 69 | * 控制主线程等待所有子线程运行结束 70 | * @param threadArrayList 要运行的线程对象列表 71 | * @param wait_thread_run_end 程同步计数器的数目 72 | */ 73 | public void threadControl(ArrayList threadArrayList, CountDownLatch wait_thread_run_end){ 74 | 75 | //开始执行多线程 76 | for (Thread thread : threadArrayList){ 77 | thread.start(); 78 | } 79 | 80 | //等待所有子线程运行结束 81 | try { 82 | wait_thread_run_end.await(); 83 | } catch (InterruptedException e){ 84 | HelpPrompt.printInfo(e.getMessage()); 85 | } 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/org/easyxms/Quit.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | class Quit { 5 | 6 | /** 7 | * 退出方法 8 | */ 9 | public static void quit(){ 10 | HelpPrompt.printAskQuit(); 11 | try { 12 | String quit = new GetInput().getInputFromStandardInput(); 13 | if ("y".equals(quit) || "Y".equals(quit) || quit.length() == 0){ 14 | System.exit(0); 15 | } 16 | } catch (Exception e){ 17 | HelpPrompt.printInfo(e.getMessage()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/org/easyxms/ResultSetToEntityMapping.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | import java.sql.ResultSet; 4 | 5 | 6 | /** 7 | * 结果集转换为实体类接口 8 | */ 9 | public interface ResultSetToEntityMapping { 10 | public Object mapping(ResultSet rs); 11 | } 12 | -------------------------------------------------------------------------------- /src/org/easyxms/ServerInfo.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | /** 5 | * 6 | * 服务器的各个信息对象 7 | * 8 | * */ 9 | class ServerInfo { 10 | 11 | private String ip = null; 12 | private String server_group = null; 13 | private String username = null; 14 | private String password = null; 15 | private int port = 22; 16 | 17 | ServerInfo(){ } 18 | 19 | ServerInfo(String ip, String server_group, 20 | String username, String password, int port) { 21 | this.ip = ip; 22 | this.server_group = server_group; 23 | this.password = password; 24 | this.username = username; 25 | this.port = port; 26 | } 27 | 28 | 29 | public String getIp() { 30 | return ip; 31 | } 32 | 33 | public void setIp(String ip) { 34 | this.ip = ip; 35 | } 36 | 37 | public String getServer_group() { 38 | return server_group; 39 | } 40 | 41 | public void setServer_group(String server_group) { 42 | this.server_group = server_group; 43 | } 44 | 45 | public String getUsername() { 46 | return username; 47 | } 48 | 49 | public void setUsername(String username) { 50 | this.username = username; 51 | } 52 | 53 | public String getPassword() { 54 | return password; 55 | } 56 | 57 | public void setPassword(String password) { 58 | this.password = password; 59 | } 60 | 61 | public int getPort() { 62 | return port; 63 | } 64 | 65 | public void setPort(int port) { 66 | this.port = port; 67 | } 68 | 69 | 70 | @Override 71 | public String toString() { 72 | return String.format("%s %s %s %s %d",this.ip,this.server_group, 73 | EncryptDecryptPassword.Decrypt(this.username), 74 | EncryptDecryptPassword.Decrypt(this.password),this.port); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/org/easyxms/ServerInfoDAO.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | 8 | /** 9 | * ServerInfo数据库访问对象类 10 | */ 11 | class ServerInfoDAO { 12 | 13 | 14 | private String insert = "insert into ServerInfo (ip,server_group,username,password,port) values(?,?,?,?,?)"; 15 | private String queryAllFieldByIP = "select * from ServerInfo where ip = ?"; 16 | private String queryAllFieldByServerGroup = "select * from ServerInfo where server_group = ?"; 17 | private String queryDistinctServerGroup = "select distinct server_group from ServerInfo"; 18 | private String queryIPServerGroup = "select ip,server_group from ServerInfo"; 19 | private String queryIPServerGroupByServerGroup = "select ip,server_group from ServerInfo where server_group = ?"; 20 | private String queryAll = "select * from ServerInfo"; 21 | private String deleteByIP = "delete from ServerInfo where ip = ?"; 22 | private String deleteByServerGroup = "delete from ServerInfo where server_group = ?"; 23 | private String deleteAll = "delete from ServerInfo"; 24 | private String createTable = "create table if not exists ServerInfo " + 25 | "(ip text not null,server_group text not null," + 26 | "username text not null default 'root',password text not null," + 27 | "port integer not null default 22)"; 28 | 29 | 30 | /** 31 | * 在初始化的时候创建表 32 | */ 33 | ServerInfoDAO() { 34 | this.createTable(); 35 | } 36 | 37 | 38 | /** 39 | * 创建表 40 | */ 41 | public void createTable(){ 42 | DBManager dbManager = new DBManager(); 43 | dbManager.create(createTable); 44 | } 45 | 46 | 47 | /** 48 | * 插入信息 49 | * @param objects ServerInfo对象列表 50 | * @return 整数数组,每一个元素代表每一条语句影响的行数 51 | */ 52 | public int[] insert(List objects){ 53 | DBManager dbManager = new DBManager(); 54 | return dbManager.insert(insert, objects, queryAllFieldByIP); 55 | } 56 | 57 | 58 | /** 59 | * 根据IP地址进行查询所有字段 60 | * @param ip 要查询的IP地址 61 | * @return 一个ServerInfo对象列表 62 | */ 63 | public List queryAllFieldByIP(String ip){ 64 | DBManager dbManager = new DBManager(); 65 | List args = new ArrayList(); 66 | args.add(ip); 67 | return dbManager.query(queryAllFieldByIP,args,new ServerInfoMapping()); 68 | } 69 | 70 | /** 71 | * 根据分组来查询所有字段 72 | * @param server_group 分组 73 | * @return 一个ServerInfo对象列表 74 | */ 75 | public List queryAllFieldByServerGroup(String server_group){ 76 | DBManager dbManager = new DBManager(); 77 | List args = new ArrayList(); 78 | args.add(server_group); 79 | return dbManager.query(queryAllFieldByServerGroup,args,new ServerInfoMapping()); 80 | } 81 | 82 | 83 | /** 84 | * 查询所有的分组 85 | * @return 一个分组字符串列表 86 | */ 87 | public List queryDistinctServerGroup(){ 88 | DBManager dbManager = new DBManager(); 89 | return dbManager.query(queryDistinctServerGroup,new ArrayList(),"group"); 90 | } 91 | 92 | 93 | /** 94 | * 查询出IP和分组 95 | * @return 一个IP分组字符串列表 96 | */ 97 | public List queryIPServerGroup(){ 98 | DBManager dbManager = new DBManager(); 99 | return dbManager.query(queryIPServerGroup,new ArrayList(),"ip_group"); 100 | } 101 | 102 | 103 | /** 104 | * 根据分组来查询IP和分组 105 | * @param server_group 分组 106 | * @return 一个IP分组字符串列表 107 | */ 108 | public List queryIPServerGroupByServerGroup(String server_group){ 109 | DBManager dbManager = new DBManager(); 110 | List args = new ArrayList(); 111 | args.add(server_group); 112 | return dbManager.query(queryIPServerGroupByServerGroup,args,"ip_group_bygroup"); 113 | } 114 | 115 | 116 | /** 117 | * 查询所有的字段 118 | * @return 一个ServerInfo对象列表 119 | */ 120 | public List queryAll(){ 121 | DBManager dbManager = new DBManager(); 122 | return dbManager.query(queryAll,new ArrayList(),new ServerInfoMapping()); 123 | } 124 | 125 | 126 | /** 127 | * 根据IP进行删除 128 | * @param ip IP地址 129 | * @return 一个整数数组,每一个元素代表每一条语句影响的行数 130 | */ 131 | public int[] deleteByIP(String ip){ 132 | DBManager dbManager = new DBManager(); 133 | List args = new ArrayList(); 134 | args.add(ip); 135 | return dbManager.delete(deleteByIP, args, queryAllFieldByIP); 136 | } 137 | 138 | 139 | /** 140 | * 根据分组进行删除 141 | * @param server_group 分组 142 | * @return 一个整数数组,每一个元素代表每一条语句影响的行数 143 | */ 144 | public int[] deleteByServerGroup(String server_group){ 145 | DBManager dbManager = new DBManager(); 146 | List args = new ArrayList(); 147 | args.add(server_group); 148 | return dbManager.delete(deleteByServerGroup,args,queryAllFieldByServerGroup); 149 | } 150 | 151 | 152 | /** 153 | * 清空表 154 | * @return 影响的的行数 155 | */ 156 | public int deleteAll(){ 157 | DBManager dbManager = new DBManager(); 158 | return dbManager.delete(deleteAll); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/org/easyxms/ServerInfoMapping.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | 7 | 8 | class ServerInfoMapping implements ResultSetToEntityMapping { 9 | 10 | 11 | /** 12 | * 把ResultSet结果集转换为ServerInfo对象 13 | * @param rs 结果集对象 14 | * @return 一个ServerInfo对象 15 | */ 16 | @Override 17 | public ServerInfo mapping(ResultSet rs) { 18 | 19 | ServerInfo serverInfo = new ServerInfo(); 20 | int i = 1; 21 | try { 22 | serverInfo = new ServerInfo(rs.getString(i++),rs.getString(i++),rs.getString(i++), 23 | rs.getString(i++),rs.getInt(i++)); 24 | } catch (SQLException e){ 25 | System.out.println(e.getMessage()); 26 | } 27 | return serverInfo; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/org/easyxms/SessionPool.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.Session; 5 | import java.util.HashMap; 6 | 7 | 8 | /** 9 | * Session连接池 10 | */ 11 | class SessionPool { 12 | 13 | private static HashMap ssh_connection_pool = null; 14 | private static HashMap sftp_connection_pool = null; 15 | 16 | public static void setSsh_connection_pool(HashMap ssh_connection_pool) { 17 | SessionPool.ssh_connection_pool = ssh_connection_pool; 18 | } 19 | 20 | public static void setSftp_connection_pool(HashMap sftp_connection_pool) { 21 | SessionPool.sftp_connection_pool = sftp_connection_pool; 22 | } 23 | 24 | public static HashMap getSsh_connection_pool() { 25 | return ssh_connection_pool; 26 | } 27 | 28 | public static HashMap getSftp_connection_pool() { 29 | return sftp_connection_pool; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/org/easyxms/SettingInfo.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.util.Properties; 8 | 9 | 10 | /** 11 | * 设置信息类 12 | */ 13 | class SettingInfo { 14 | 15 | private static int enable_http_proxy = 0; 16 | private static String http_proxy_server = null; 17 | private static int http_proxy_port = 80; 18 | private static int connect_timeout = 2000; 19 | private static int sleep_time = 300; 20 | 21 | /** 22 | * 从properties文件中读取信息 23 | * */ 24 | public static Properties getConfigureFromPropertiesFile(){ 25 | Properties properties = new Properties(); 26 | try { 27 | FileInputStream fileInputStream = new FileInputStream("conf/configure.properties"); 28 | properties.load(fileInputStream); 29 | fileInputStream.close(); 30 | } catch (FileNotFoundException e){ 31 | HelpPrompt.printInfo(e.getMessage()); 32 | System.exit(1); 33 | } catch (IOException ex){ 34 | HelpPrompt.printInfo(ex.getMessage()); 35 | System.exit(1); 36 | } 37 | return properties; 38 | } 39 | 40 | 41 | /** 42 | * 读取配置文件并设置 43 | */ 44 | public static void settingInfo(){ 45 | 46 | Properties properties = getConfigureFromPropertiesFile(); 47 | 48 | //设置HTTP代理相关 49 | enable_http_proxy = Integer.parseInt(properties.getProperty("enable_http_proxy")); 50 | if (enable_http_proxy == 1 ){ 51 | http_proxy_server = properties.getProperty("http_proxy_server"); 52 | http_proxy_port = Integer.parseInt(properties.getProperty("http_proxy_port")); 53 | } 54 | 55 | //设置连接服务器时超时时间 56 | connect_timeout = Integer.parseInt(properties.getProperty("connect_time_out")); 57 | 58 | //设置子线程的睡眠时间 59 | sleep_time = Integer.parseInt(properties.getProperty("sleep_time")); 60 | 61 | } 62 | 63 | public static int getEnable_http_proxy() { 64 | return enable_http_proxy; 65 | } 66 | 67 | public static String getHttp_proxy_server() { 68 | return http_proxy_server; 69 | } 70 | 71 | public static int getHttp_proxy_port() { 72 | return http_proxy_port; 73 | } 74 | 75 | public static int getConnect_timeout() { 76 | return connect_timeout; 77 | } 78 | 79 | public static int getSleep_time() { 80 | return sleep_time; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/org/easyxms/TransferFile.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | 5 | public interface TransferFile { 6 | public void transfer(); 7 | } 8 | -------------------------------------------------------------------------------- /src/org/easyxms/UploadFile.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | 4 | import com.jcraft.jsch.*; 5 | import java.io.File; 6 | import java.util.concurrent.CountDownLatch; 7 | 8 | 9 | class UploadFile extends ConnectServer implements TransferFile,Runnable { 10 | 11 | private String ip = null; 12 | private Session session = null; 13 | private static String src = null; 14 | private static String dst = null; 15 | private static int is_use_session_pool = 0; //是否使用session会话池 16 | private static WriteLog writeLog = null; 17 | private static CountDownLatch countDownLatch = null; 18 | private ServerInfo serverInfo = null; 19 | 20 | 21 | UploadFile(ServerInfo serverInfo) { 22 | this.serverInfo = serverInfo; 23 | this.ip = serverInfo.getIp(); 24 | } 25 | 26 | public static void setSrc(String src) { 27 | UploadFile.src = src; 28 | } 29 | 30 | public static void setDst(String dst) { 31 | UploadFile.dst = dst; 32 | } 33 | 34 | public static void setCountDownLatch(CountDownLatch countDownLatch) { 35 | UploadFile.countDownLatch = countDownLatch; 36 | } 37 | 38 | public static void setIs_use_session_pool(int is_use_session_pool) { 39 | UploadFile.is_use_session_pool = is_use_session_pool; 40 | } 41 | 42 | public static void setWriteLog(WriteLog writeLog) { 43 | UploadFile.writeLog = writeLog; 44 | } 45 | 46 | 47 | @Override 48 | public void run() { 49 | openExecCommandChannel(); 50 | countDownLatch.countDown(); 51 | } 52 | 53 | /** 54 | * 打开SFTP通道 55 | */ 56 | public void openExecCommandChannel(){ 57 | session = connectServerOpenSession(serverInfo,writeLog); 58 | if (session.isConnected()){ 59 | //把session会话放到 session连接池中,以备下一次使用 60 | SessionPool.getSftp_connection_pool().put(ip, session); 61 | transfer(); 62 | } 63 | } 64 | 65 | 66 | /** 67 | * 上传文件 68 | */ 69 | @Override 70 | public void transfer() { 71 | try { 72 | ChannelSftp channelSftp = (ChannelSftp)session.openChannel("sftp"); 73 | channelSftp.setEnv("LC_MESSAGES", "en_US.UTF-8"); 74 | channelSftp.connect(); 75 | channelSftp.put(src, dst, new FileTransferProgressMonitor()); 76 | dst=(dst.startsWith("/"))?dst:channelSftp.getHome() + "/" + dst; 77 | writeLog.writeFileUpload(String.format("Upload %s To %s@%s",(new File(src).getAbsoluteFile()),dst,ip)); 78 | channelSftp.disconnect(); 79 | } catch (JSchException e){ 80 | HelpPrompt.printInfo(ip + " " + e.getMessage()); 81 | } catch (SftpException e){ 82 | HelpPrompt.printInfo(ip + " " + e.getMessage()); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/org/easyxms/WriteLog.java: -------------------------------------------------------------------------------- 1 | package org.easyxms; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | 7 | /** 8 | * 写日志类 9 | */ 10 | class WriteLog { 11 | 12 | private static Log log_command = LogFactory.getLog("command_history"); 13 | private static Log log_commmand_result = LogFactory.getLog("command_result"); 14 | private static Log log_upload_file = LogFactory.getLog("upload_file"); 15 | 16 | 17 | /** 18 | * 写执行过的命令到日志 19 | * @param command 执行的命令 20 | */ 21 | public void writeCommand(String command){ 22 | log_command.info(command); 23 | } 24 | 25 | 26 | /** 27 | * 写命令执行的结果到日志 28 | * @param result 命令执行的结果 29 | */ 30 | public void writeCommandResult(String result){ 31 | log_commmand_result.info(result); 32 | } 33 | 34 | 35 | /** 36 | * 写 文件上传记录到文件 37 | * @param file_upload 文件上传结果的字符串 38 | */ 39 | public void writeFileUpload(String file_upload){ 40 | log_upload_file.info(file_upload); 41 | } 42 | } 43 | --------------------------------------------------------------------------------