/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.brooklyn.rest.resources; import org.apache.brooklyn.rest.api.ScriptApi; import org.apache.brooklyn.rest.domain.ScriptExecutionSummary; import org.apache.brooklyn.util.stream.ThreadLocalPrintStream; import org.apache.brooklyn.util.stream.ThreadLocalPrintStream.OutputCapturingContext; import groovy.lang.Binding; import groovy.lang.GroovyShell; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.LinkedHashMap; import java.util.Map; public class ScriptResource extends AbstractBrooklynRestResource implements ScriptApi { private static final Logger log = LoggerFactory.getLogger(ScriptResource.class); public static final String USER_DATA_MAP_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.data"; public static final String USER_LAST_VALUE_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.last"; @SuppressWarnings("rawtypes") @Override public ScriptExecutionSummary groovy(HttpServletRequest request, String script) { log.info("Web REST executing user-supplied script"); if (log.isDebugEnabled()) { log.debug("Web REST user-supplied script contents:\n"+script); } Binding binding = new Binding(); binding.setVariable("mgmt", mgmt()); HttpSession session = request!=null ? request.getSession() : null; if (session!=null) { Map data = (Map) session.getAttribute(USER_DATA_MAP_SESSION_ATTRIBUTE); if (data==null) { data = new LinkedHashMap(); session.setAttribute(USER_DATA_MAP_SESSION_ATTRIBUTE, data); } binding.setVariable("data", data); Object last = session.getAttribute(USER_LAST_VALUE_SESSION_ATTRIBUTE); binding.setVariable("last", last); } GroovyShell shell = new GroovyShell(binding); OutputCapturingContext stdout = ThreadLocalPrintStream.stdout().captureTee(); OutputCapturingContext stderr = ThreadLocalPrintStream.stderr().captureTee(); Object value = null; Throwable problem = null; try { value = shell.evaluate(script); if (session!=null) session.setAttribute(USER_LAST_VALUE_SESSION_ATTRIBUTE, value); } catch (Throwable t) { log.warn("Problem in user-supplied script: "+t, t); problem = t; } finally { stdout.end(); stderr.end(); } if (log.isDebugEnabled()) { log.debug("Web REST user-supplied script completed:\n"+ (value!=null ? "RESULT: "+value.toString()+"\n" : "")+ (problem!=null ? "ERROR: "+problem.toString()+"\n" : "")+ (!stdout.isEmpty() ? "STDOUT: "+stdout.toString()+"\n" : "")+ (!stderr.isEmpty() ? "STDERR: "+stderr.toString()+"\n" : "")); } // call toString on the result, in case it is not serializable return new ScriptExecutionSummary( value!=null ? value.toString() : null, problem!=null ? problem.toString() : null, stdout.toString(), stderr.toString()); } }