| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.alibaba.jstorm.daemon.supervisor; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.LineNumberReader; |
| import java.io.PrintWriter; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.UUID; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import backtype.storm.Config; |
| import backtype.storm.utils.Utils; |
| |
| import com.alibaba.jstorm.client.ConfigExtension; |
| import com.alibaba.jstorm.cluster.StormConfig; |
| |
| /** |
| * Right now generate java sandbox policy through template file |
| * |
| * In the future, generating java sandbox policy will through hardcode |
| * |
| * @author longda |
| * @version |
| */ |
| public class SandBoxMaker { |
| private static final Logger LOG = LoggerFactory.getLogger(SandBoxMaker.class); |
| |
| public static final String SANBOX_TEMPLATE_NAME = "sandbox.policy"; |
| |
| public static final String JSTORM_HOME_KEY = "%JSTORM_HOME%"; |
| |
| public static final String CLASS_PATH_KEY = "%CLASS_PATH%"; |
| |
| public static final String LOCAL_DIR_KEY = "%JSTORM_LOCAL_DIR%"; |
| |
| // this conf should only be Supervisor Conf |
| private final Map conf; |
| |
| private final boolean isEnable; |
| |
| private final Map<String, String> replaceBaseMap = new HashMap<String, String>(); |
| |
| public SandBoxMaker(Map conf) { |
| this.conf = conf; |
| |
| isEnable = ConfigExtension.isJavaSandBoxEnable(conf); |
| |
| LOG.info("Java Sandbox Policy :" + String.valueOf(isEnable)); |
| |
| String jstormHome = System.getProperty("jstorm.home"); |
| if (jstormHome == null) { |
| jstormHome = "./"; |
| } |
| |
| replaceBaseMap.put(JSTORM_HOME_KEY, jstormHome); |
| |
| replaceBaseMap.put(LOCAL_DIR_KEY, (String) conf.get(Config.STORM_LOCAL_DIR)); |
| |
| LOG.info("JSTORM_HOME is " + jstormHome); |
| } |
| |
| private String genClassPath(String classPathLine) { |
| StringBuilder sb = new StringBuilder(); |
| |
| String[] classPathes = classPathLine.split(":"); |
| for (String classpath : classPathes) { |
| if (StringUtils.isBlank(classpath)) { |
| continue; |
| } |
| |
| File file = new File(classpath); |
| if (file.isDirectory()) { |
| sb.append(" permission java.io.FilePermission \""); |
| sb.append(classpath).append(File.separator).append("**"); |
| sb.append("\", \"read\";\n"); |
| } else { |
| sb.append(" permission java.io.FilePermission \""); |
| sb.append(classpath); |
| sb.append("\", \"read\";\n"); |
| } |
| |
| } |
| |
| return sb.toString(); |
| } |
| |
| private String replaceLine(String line, Map<String, String> replaceMap) { |
| |
| for (Entry<String, String> entry : replaceMap.entrySet()) { |
| if (line.contains(CLASS_PATH_KEY)) { |
| return genClassPath(entry.getValue()); |
| } else if (line.contains(entry.getKey())) { |
| return line.replace(entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| return line; |
| } |
| |
| public String generatePolicyFile(Map<String, String> replaceMap) throws IOException { |
| // dynamic generate policy file, no static file |
| String tmpPolicy = StormConfig.supervisorTmpDir(conf) + File.separator + UUID.randomUUID().toString(); |
| |
| InputStream inputStream = SandBoxMaker.class.getClassLoader().getResourceAsStream(SANBOX_TEMPLATE_NAME); |
| |
| PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tmpPolicy))); |
| |
| try { |
| |
| InputStreamReader inputReader = new InputStreamReader(inputStream); |
| |
| BufferedReader reader = new BufferedReader(new LineNumberReader(inputReader)); |
| |
| String line = null; |
| while ((line = reader.readLine()) != null) { |
| String replaced = replaceLine(line, replaceMap); |
| |
| writer.println(replaced); |
| } |
| |
| return tmpPolicy; |
| } catch (Exception e) { |
| LOG.error("Failed to generate policy file\n", e); |
| throw new IOException(e); |
| } finally { |
| if (inputStream != null) { |
| inputStream.close(); |
| } |
| if (writer != null) { |
| writer.close(); |
| } |
| |
| } |
| } |
| |
| /** |
| * Generate command string |
| * |
| * @param workerId |
| * @return |
| * @throws IOException |
| */ |
| public String sandboxPolicy(String workerId, Map<String, String> replaceMap) throws IOException { |
| if (isEnable == false) { |
| return ""; |
| } |
| |
| replaceMap.putAll(replaceBaseMap); |
| |
| String tmpPolicy = generatePolicyFile(replaceMap); |
| |
| File file = new File(tmpPolicy); |
| String policyPath = StormConfig.worker_root(conf, workerId) + File.separator + SANBOX_TEMPLATE_NAME; |
| File dest = new File(policyPath); |
| file.renameTo(dest); |
| |
| StringBuilder sb = new StringBuilder(); |
| sb.append(" -Djava.security.manager -Djava.security.policy="); |
| sb.append(policyPath); |
| |
| return sb.toString(); |
| |
| } |
| |
| public static void main(String[] args) { |
| Map<Object, Object> conf = Utils.readStormConfig(); |
| |
| conf.put("java.sandbox.enable", Boolean.valueOf(true)); |
| |
| SandBoxMaker maker = new SandBoxMaker(conf); |
| |
| try { |
| System.out.println("sandboxPolicy:" + maker.sandboxPolicy("simple", new HashMap<String, String>())); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| } |