blob: cdf8cdcae52ea66b8cc97b8baf6181e55f30e326 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
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
https://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.
-->
<head>
<title>Apache Felix - Apache Felix Script Console Plugin</title>
<link rel="icon" href="/res/favicon.ico">
<link rel="stylesheet" href="/res/site.css" type="text/css" media="all">
<link rel="stylesheet" href="/res/codehilite.css" type="text/css" media="all">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
</head>
<body>
<div class="title">
<div class="logo">
<a href="https://felix.apache.org/">
<img border="0" alt="Apache Felix" src="/res/logo.png">
</a>
</div>
<div class="header">
<a href="https://www.apache.org/">
<img border="0" alt="Apache" src="/res/apache.png">
</a>
</div>
</div>
<div class="menu">
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<p><a href="/news.html">News</a> <br />
<a href="/license.html">License</a> <br />
<a href="/downloads.cgi">Downloads</a> <br />
<a href="/documentation.html">Documentation</a> <br />
<a href="/documentation/community/project-info.html">Project Info</a> <br />
<a href="/documentation/community/contributing.html">Contributing</a> <br />
<a href="/sitemap.html">Site Map</a> <br />
<a href="https://www.apache.org/">ASF</a> <br />
<a href="https://www.apache.org/security/">Security</a> <br />
<a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a> <br />
<a href="https://www.apache.org/foundation/thanks.html">Sponsors</a> </p>
<iframe
src="https://www.apache.org/ads/button.html"
style="border-width:0; float: left"
frameborder="0"
scrolling="no"
width="135"
height="135">
</iframe>
</div>
<div class="main">
<div class="breadcrump" style="font-size: 80%;">
<a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/documentation.html">Documentation</a>
</div>
<h1>Apache Felix Script Console Plugin</h1>
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<style type="text/css">
img {
width:auto;
}
</style>
<p>Script Console is a Felix web console plugin which allows evaluation of scripts within the OSGi container. It provides following
features</p>
<ul>
<li>Support evaluation of script in any e.g. Groovy, JavaScript, Ruby etc. You would need to ensure that relevant language bundle is deployed</li>
<li>Code editor with syntax highlighting support based on <a href="http://codemirror.net/">CodeMirror</a> Javascript library</li>
<li>Hot key support</li>
<li>Execute remote testcase via evaluating test scripts</li>
</ul>
<h3 id="installation">Installation<a class="headerlink" href="#installation" title="Permanent link">&para;</a></h3>
<p>To make use of this plugin you need to</p>
<h4 id="a-install-the-script-console-plugin-bundle">A - Install the Script Console Plugin bundle<a class="headerlink" href="#a-install-the-script-console-plugin-bundle" title="Permanent link">&para;</a></h4>
<p>Refer to <a href="http://felix.apache.org/downloads.cgi">downloads</a> for getting the bundle.</p>
<p>For Maven use following coordinates</p>
<div class="codehilite"><pre><span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.felix<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>org.apache.felix.webconsole.plugins.scriptconsole<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.0.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</pre></div>
<p>For latest build follow steps below</p>
<div class="codehilite"><pre>$<span class="n">svn</span> <span class="n">co</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">svn</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">org</span><span class="o">/</span><span class="n">repos</span><span class="o">/</span><span class="n">asf</span><span class="o">/</span><span class="n">felix</span><span class="o">/</span><span class="n">trunk</span><span class="o">/</span><span class="n">webconsole</span><span class="o">-</span><span class="n">plugins</span><span class="o">/</span><span class="n">script</span><span class="o">-</span><span class="n">console</span><span class="o">/</span>
$<span class="n">cd</span> <span class="n">script</span><span class="o">-</span><span class="n">console</span>
$<span class="n">mvn</span> <span class="n">clean</span> <span class="n">install</span>
$<span class="n">mvn</span> <span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">:</span><span class="n">maven</span><span class="o">-</span><span class="n">sling</span><span class="o">-</span><span class="n">plugin</span><span class="p">:</span>2<span class="p">.</span>1<span class="p">.</span>0<span class="p">:</span><span class="n">install</span> <span class="o">-</span><span class="n">Dsling</span><span class="p">.</span><span class="n">url</span><span class="p">=</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">localhost</span><span class="p">:</span>8080<span class="o">/</span><span class="n">system</span><span class="o">/</span><span class="n">console</span>
</pre></div>
<h4 id="b-install-the-language-specific-bundle">B- Install the language specific bundle<a class="headerlink" href="#b-install-the-language-specific-bundle" title="Permanent link">&para;</a></h4>
<p>Install bundles for the Script Language you want to use</p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.1.6/groovy-all-2.1.6.jar">Groovy</a></li>
<li><a href="http://repo1.maven.org/maven2/org/jruby/jruby/1.7.4/jruby-1.7.4.jar">JRuby</a></li>
</ul>
<h3 id="usage">Usage<a class="headerlink" href="#usage" title="Permanent link">&para;</a></h3>
<p>After installing it you would see a new tab "Script Console" in Felix Web Console.
The plugin screen provides a textarea to author script code. One can select the language via the given dropdown. The generated
output is shown in pane below.</p>
<p>The script exposes following variables</p>
<ul>
<li><code>request</code> - Current HttpServletRequest instance</li>
<li><code>response</code> - Current HttpServletResponse instance</li>
<li><code>reader</code> - Direct access to the Reader of the request - same as request.getReader(). Use it for reading the data of an HTTP request body.</li>
<li><code>out</code> - Direct access to the PrintWriter of the response - same as response.getWriter(). Use it for writing to the HTTP response body.</li>
<li><code>osgi</code> - Provides convenience methods for scripts, mainly osgi.getService(foo.bar.Service.class) to retrieve OSGi services available in
OSGi Container (Class notation depending on scripting language).</li>
<li><code>bundleContext</code> - OSGi BundleContext instance for the script console plugin bundle. Can be used to access the OSGi runtime</li>
</ul>
<p>So simplest script that can work is</p>
<div class="codehilite"><pre><span class="n">out</span><span class="o">.</span><span class="na">println</span> <span class="o">(</span><span class="s2">&quot;Hello world!!&quot;</span><span class="o">);</span>
</pre></div>
<p>To access a service use <code>osgi.getService</code></p>
<div class="codehilite"><pre><span class="kt">def</span> <span class="n">httpService</span> <span class="o">=</span> <span class="n">osgi</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">org</span><span class="o">.</span><span class="na">osgi</span><span class="o">.</span><span class="na">service</span><span class="o">.</span><span class="na">http</span><span class="o">.</span><span class="na">HttpService</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
</pre></div>
<p>To access a service satisfying OSGi filter</p>
<div class="codehilite"><pre><span class="kt">def</span> <span class="n">eventPlugin</span> <span class="o">=</span> <span class="n">osgi</span><span class="o">.</span><span class="na">getServices</span><span class="o">(</span><span class="n">javax</span><span class="o">.</span><span class="na">servlet</span><span class="o">.</span><span class="na">Servlet</span><span class="o">.</span><span class="na">class</span><span class="o">,</span><span class="s1">&#39;(felix.webconsole.label=events)&#39;</span><span class="o">)[</span><span class="mi">0</span><span class="o">]</span>
</pre></div>
<p>Following hotkeys work</p>
<ul>
<li>Ctrl+F9 - Execute the script</li>
<li>Ctrl+q - Clear the output</li>
</ul>
<h3 id="http-api">HTTP API<a class="headerlink" href="#http-api" title="Permanent link">&para;</a></h3>
<p>The plugin can also be invoked by making POST request. It supports following parameters</p>
<ul>
<li><code>code</code>- Script content. Can be norm form data or a multi part content</li>
<li><code>lang</code> - Language extension.<ul>
<li>Groovy - groovy</li>
<li>JavaScript - esp</li>
</ul>
</li>
</ul>
<p>If any exception occurs while evaluating the script then it would return the exception message with status set to 500. Scripts can control what output they want to emit.</p>
<h3 id="sample-scripts">Sample Scripts<a class="headerlink" href="#sample-scripts" title="Permanent link">&para;</a></h3>
<p>Following are some sample scripts in Groovy. Note the scripts might be depending on implementation details to access the
relevant data structures</p>
<ol>
<li>
<p>Script to find out servlets which are registered problematically with Felix HTTP Service</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">org.osgi.service.http.HttpService</span>
<span class="kn">import</span> <span class="nn">org.osgi.framework.FrameworkUtil</span>
<span class="kn">import</span> <span class="nn">org.osgi.framework.Bundle</span>
<span class="kt">def</span> <span class="n">httpService</span> <span class="o">=</span> <span class="n">osgi</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">HttpService</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="n">httpService</span><span class="o">.</span><span class="na">handlerRegistry</span><span class="o">.</span><span class="na">aliasMap</span><span class="o">.</span><span class="na">each</span><span class="o">{</span><span class="n">alias</span><span class="o">,</span><span class="n">servlet</span> <span class="o">-&gt;</span>
<span class="n">Bundle</span> <span class="n">bnd</span> <span class="o">=</span> <span class="n">FrameworkUtil</span><span class="o">.</span><span class="na">getBundle</span><span class="o">(</span><span class="n">servlet</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="n">println</span> <span class="s2">&quot;$alias : ${servlet.class.name} ($bnd.symbolicName)&quot;</span>
<span class="o">}</span>
</pre></div>
</li>
<li>
<p>Script to load a class which is not exported and then invoke some static method on that class. At times you need to
access some private class to see the runtime state.</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">org.osgi.framework.Bundle</span>
<span class="kn">import</span> <span class="nn">org.osgi.framework.BundleContext</span>
<span class="c1">//Script to load a class which is not exported and then invoke some static method on that class</span>
<span class="c1">//Name of the class</span>
<span class="kt">def</span> <span class="n">className</span> <span class="o">=</span> <span class="s2">&quot;org.apache.sling.engine.impl.SlingMainServlet&quot;</span>
<span class="kt">def</span> <span class="n">resPath</span> <span class="o">=</span> <span class="n">className</span><span class="o">.</span><span class="na">replaceAll</span><span class="o">(</span><span class="s1">&#39;.&#39;</span><span class="o">,</span><span class="s1">&#39;/&#39;</span><span class="o">)+</span><span class="s2">&quot;.class&quot;</span>
<span class="kt">def</span> <span class="n">bundles</span> <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">getBundles</span><span class="o">().</span><span class="na">findAll</span><span class="o">{</span><span class="n">Bundle</span> <span class="n">b</span> <span class="o">-&gt;</span>
<span class="n">b</span><span class="o">.</span><span class="na">getEntry</span><span class="o">(</span><span class="n">resPath</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span>
<span class="o">}</span>
<span class="k">if</span><span class="o">(!</span><span class="n">bundles</span><span class="o">){</span>
<span class="n">println</span> <span class="s2">&quot;No bundle found for class $className&quot;</span>
<span class="k">return</span>
<span class="o">}</span>
<span class="kt">def</span> <span class="n">b</span> <span class="o">=</span> <span class="n">bundles</span><span class="o">.</span><span class="na">asList</span><span class="o">().</span><span class="na">first</span><span class="o">()</span>
<span class="kt">def</span> <span class="n">clazz</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="na">loadClass</span><span class="o">(</span><span class="n">className</span><span class="o">)</span>
<span class="c1">//Invoke some static method</span>
<span class="kt">def</span> <span class="n">result</span> <span class="o">=</span> <span class="n">clazz</span><span class="o">.</span><span class="na">metaClass</span><span class="o">.</span><span class="na">invokeStaticMethod</span><span class="o">(</span><span class="n">clazz</span><span class="o">,</span> <span class="s1">&#39;foo&#39;</span><span class="o">,</span> <span class="n">arg1</span><span class="o">)</span>
<span class="n">println</span> <span class="n">result</span>
</pre></div>
</li>
<li>
<p>Script to find out which bundle embeds a given class</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">org.osgi.framework.Bundle</span>
<span class="kn">import</span> <span class="nn">org.osgi.framework.BundleContext</span>
<span class="c1">//Name of the class</span>
<span class="kt">def</span> <span class="n">className</span> <span class="o">=</span> <span class="s2">&quot;org.apache.sling.engine.impl.SlingMainServlet&quot;</span>
<span class="kt">def</span> <span class="n">resPath</span> <span class="o">=</span> <span class="n">className</span><span class="o">.</span><span class="na">replaceAll</span><span class="o">(</span><span class="s1">&#39;.&#39;</span><span class="o">,</span><span class="s1">&#39;/&#39;</span><span class="o">)+</span><span class="s2">&quot;.class&quot;</span>
<span class="kt">def</span> <span class="n">bundles</span> <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">getBundles</span><span class="o">().</span><span class="na">findAll</span><span class="o">{</span><span class="n">Bundle</span> <span class="n">b</span> <span class="o">-&gt;</span>
<span class="n">b</span><span class="o">.</span><span class="na">getEntry</span><span class="o">(</span><span class="n">resPath</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span>
<span class="o">}</span>
<span class="n">println</span> <span class="s2">&quot;Following bundles have the class&quot;</span>
<span class="n">bundles</span><span class="o">.</span><span class="na">each</span><span class="o">{</span>
<span class="n">println</span> <span class="n">it</span>
<span class="o">}</span>
</pre></div>
</li>
</ol>
<h3 id="screenshots">Screenshots<a class="headerlink" href="#screenshots" title="Permanent link">&para;</a></h3>
<p><img src="script-console-1.png" align="center"></p>
<div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
Rev. 1508319 by chetanm on Tue, 30 Jul 2013 06:53:12 +0000
</div>
<div class="trademarkFooter">
Apache Felix, Felix, Apache, the Apache feather logo, and the Apache Felix project
logo are trademarks of The Apache Software Foundation. All other marks mentioned
may be trademarks or registered trademarks of their respective owners.
</div>
</div>
</body>
</html>