Github user kevinxu021 commented on a diff in the pull request:
https://github.com/apache/incubator-trafodion/pull/203#discussion_r46641349
--- Diff: core/conn/spj_init/src/main/java/com/traf/mgmt/JarFileMgmt.java
---
@@ -0,0 +1,435 @@
+/**
+* @@@ START COPYRIGHT @@@
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+* @@@ END COPYRIGHT @@@
+ */
+package com.traf.mgmt;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xerial.snappy.Snappy;
+
+public class JarFileMgmt {
+ private static final Logger LOG =
LoggerFactory.getLogger(JarFileMgmt.class);
+ private static final String url = "jdbc:default:connection";
+ // 100Mb
+ private static final long MAX_JAR_FILE_SIZE = 104857600;
+ private static final SimpleDateFormat format = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ private static final int MaxDataSize = 102400;
+ private static final String CHARTSET = "ISO-8859-1";
+
+ /**
+ * Print help info
+ *
+ * @param helps:
+ * INOUT parameter like PUT/LS/...
+ */
+ public static void help(String[] helps) {
+ String[] help = new String[] {
+ "PUT - Upload a JAR. SHOWDDL PROCEDURE
DEFAULT_SPJ.PUT for more info.",
+ "LS - List JARs. SHOWDDL PROCEDURE
DEFAULT_SPJ.LS for more info.",
+ "LSALL - List all JARs. SHOWDDL PROCEDURE
DEFAULT_SPJ.LSALL for more info.",
+ "RM - Remove a JAR. SHOWDDL PROCEDURE
DEFAULT_SPJ.RM for more info.",
+ "RMREX - Remove JARs by a perticular pattern.
SHOWDDL PROCEDURE DEFAULT_SPJ.RMREX for more info.",
+ "GETFILE - Download a JAR. SHOWDDL PROCEDURE
DEFAULT_SPJ.GETFILE for more info."
+ };
+ List<String> index = new ArrayList<String>(help.length);
+ index.add("PUT");
+ index.add("LS");
+ index.add("LSALL");
+ index.add("RM");
+ index.add("RMREX");
+ index.add("GETFILE");
+ String tmp = helps[0].trim().toUpperCase();
+ helps[0] = "HELP:\r\n";
+ switch (index.indexOf(tmp)) {
+ case 0:
+ helps[0] = help[0];
+ break;
+ case 1:
+ helps[0] = help[1];
+ break;
+ case 2:
+ helps[0] = help[2];
+ break;
+ case 3:
+ helps[0] = help[3];
+ break;
+ case 4:
+ helps[0] = help[4];
+ break;
+ case 5:
+ helps[0] = help[5];
+ break;
+ default:
+ for (String h : help) {
+ helps[0] += h + "\r\n";
+ }
+
+ }
+
+ }
+
+ public static void syncJar(String userPath, String fileName) throws
SQLException, IOException {
+ checkFileName(fileName);
+ LOG.info("syncJars " + fileName);
+ String nodes = System.getenv("MY_NODES");
+ if (nodes != null && !"".equals(nodes.trim())) {
+ execShell("pdcp " + nodes + " " + userPath +
fileName.trim() + " " + userPath + " ");
+ }
+ }
+
+ private static String execShell(String cmd) throws IOException {
+ Process p = Runtime.getRuntime().exec(cmd);
+ if (p != null) {
+ StringBuilder sb = new StringBuilder();
+ InputStream in = null;
+ try {
+ in = p.getInputStream();
+ int c = -1;
+ while ((c = in.read()) != -1) {
+ sb.append((char) c);
+ }
+ } finally {
+ if (in != null)
+ in.close();
+ }
+ try {
+ in = p.getErrorStream();
+ int c = -1;
+ boolean flag = true;
+ while ((c = in.read()) != -1) {
+ if (flag) {
+ sb.append("\r\n");
+ } else {
+ flag = false;
+ }
+ sb.append((char) c);
+ }
+ } finally {
+ if (in != null)
+ in.close();
+ }
+ return sb.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Download a JAR file
+ *
+ * @param fileName
+ * @param offset
+ * @param fileData
+ * @throws SQLException
+ * @throws IOException
+ */
+ public static void get(String fileName, int offset, String[] fileData,
long[] fileLength)
+ throws SQLException, IOException {
+ checkFileName(fileName);
+ Connection conn = getConn();
+ LOG.info("Get " + fileName);
+ String userPath = getCodeFilePath(conn);
+ close(conn);
+ File file = new File(userPath + fileName);
+ if (!file.exists()) {
+ throw new SQLException("No such file[" + fileName +
"]");
+ }
+ RandomAccessFile rAFile = null;
+ try {
+ rAFile = new RandomAccessFile(file, "r");
+ rAFile.seek(offset);
+ byte bArray[] = new byte[MaxDataSize];
+ int bytesRead = rAFile.read(bArray, 0, MaxDataSize);
+ if (bytesRead != -1) {
+ fileData[0] = new
String(Snappy.compress(Arrays.copyOf(bArray, bytesRead)), CHARTSET);
+ fileLength[0] = file.length();
+ LOG.info("Download: " + fileName + ", offset:"
+ offset + ",compressed length:" + fileData[0].length()
+ + ",file length:" +
fileLength[0]);
+ }
+ } finally {
+ if (rAFile != null) {
+ try {
+ rAFile.close();
+ } catch (Exception e) {
+ LOG.warn("Something wrong while close
file[" + fileName + "] stream: " + e.getMessage());
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Remove exact file
+ *
+ * @param fileName
+ * @throws SQLException
+ */
+ public static void rm(String fileName) throws SQLException {
+ checkFileName(fileName);
+ Connection conn = getConn();
+ LOG.info("Remove " + fileName);
+ String userPath = getCodeFilePath(conn);
+ close(conn);
+ File file = new File(userPath + fileName);
+ if (file.exists()) {
+ file.delete();
+ LOG.info("Remove " + fileName + " successfully!");
+ return;
+ } else {
+ throw new SQLException("No such file[" + fileName +
"]");
+ }
+ }
+
+ /**
+ * Remove files via regular formulation
+ *
+ * @param pattern:
+ * to be deleted
+ * @param names
+ * : file names to be deleted
+ * @throws SQLException
+ */
+ public static void rmRex(String pattern, String[] names) throws
SQLException {
+ checkFileName(pattern);
+ Connection conn = getConn();
+ LOG.info("Try to remove files[" + pattern + "]");
+ String userPath = getCodeFilePath(conn);
+ close(conn);
+ File[] files = getFiles(pattern, new File(userPath));
+ StringBuilder sb = new StringBuilder();
+ sb.append("<rmRex>");
+ sb.append(toXML(files, "rmList"));
+ sb.append("<message>");
+ boolean hasError = false;
+ for (File f : files) {
+ try {
+ f.delete();
+ } catch (Exception e) {
+ hasError = true;
+ LOG.error(e.getMessage(), e);
+ sb.append("<error fileName='" + f.getName() +
"'>" + e.getMessage() + "</error>");
+ }
+ }
+ if (!hasError) {
+ sb.append("Remove the files successfully!");
+ }
+ sb.append("</message>");
+ sb.append("</rmRex>");
+ names[0] = sb.toString();
+ LOG.info("Done for removing files[" + pattern + "].");
+ }
+
+ public static void lsAll(String[] names) throws SQLException {
+ ls("*", names);
+ }
+
+ /**
+ * list the Jars matching PATTERN
+ *
+ * @param pattern:
+ * @param names
+ * @throws SQLException
+ */
+ public static void ls(String pattern, String[] names) throws
SQLException {
+ checkFileName(pattern);
+ Connection conn = getConn();
+ LOG.info("List files[" + pattern + "]");
+ String userPath = getCodeFilePath(conn);
+ close(conn);
+ File dir = new File(userPath);
+ if (!dir.exists() || !dir.isDirectory()) {
+ LOG.error("Directory [" + userPath + "] is not found!");
+ throw new SQLException("Directory [" + userPath + "] is
not found!");
+ }
+ if (pattern == null) {
+ LOG.error("File pattern should not be empty!");
+ throw new SQLException("Pattern is empty!");
+ }
+ File[] files = getFiles(pattern, dir);
+ names[0] = toXML(files, "ls");
+ }
+
+ /**
+ * upload a JAR file
+ *
+ * @param fileData
+ * @param fileName
+ * @param appendFlag
+ * 0: append; otherwise overwrite
+ * @throws SQLException
+ */
+ public static void put(String fileData, String fileName, int
appendFlag) throws SQLException {
+ checkFileName(fileName);
+ try {
+ byte[] data = fileData.getBytes(CHARTSET);
+
+ Connection conn = getConn();
+ LOG.info("Put " + fileName + ", length: " + data.length
+ ", file string length:" + fileData.length());
+ String userPath = getCodeFilePath(conn);
+ close(conn);
+ String fname = userPath + fileName;
+ checkFile(fname, data.length);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(fname, (appendFlag
== 0));
+
+ fos.write(Snappy.uncompress(Arrays.copyOf(data,
data.length)));
+ fos.flush();
+ } finally {
+ if (fos != null)
+ fos.close();
+ }
+
+ syncJar(userPath, fileName);
+
+ } catch (Throwable t) {
+ LOG.error(t.getMessage(), t);
+ throw new SQLException(t.getMessage());
+ }
+ }
+
+ private static void checkFileName(String fileName) throws SQLException {
+ if (fileName.contains("/") || fileName.contains("\\"))
+ throw new SQLException("Illegal file name: " + fileName
+ + ". File name must not contain
\"/\".");
--- End diff --
'/' and '\' is not allowed, so I think ".." may be ok because "../xxx" is
not allowed and "..filename" is ok to be a file name.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---