| <!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> » <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">¶</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">¶</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"><dependency></span> |
| <span class="nt"><groupId></span>org.apache.felix<span class="nt"></groupId></span> |
| <span class="nt"><artifactId></span>org.apache.felix.webconsole.plugins.scriptconsole<span class="nt"></artifactId></span> |
| <span class="nt"><version></span>1.0.0<span class="nt"></version></span> |
| <span class="nt"></dependency></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">¶</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">¶</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">"Hello world!!"</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">'(felix.webconsole.label=events)'</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">¶</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">¶</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">-></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">"$alias : ${servlet.class.name} ($bnd.symbolicName)"</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">"org.apache.sling.engine.impl.SlingMainServlet"</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">'.'</span><span class="o">,</span><span class="s1">'/'</span><span class="o">)+</span><span class="s2">".class"</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">-></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">"No bundle found for class $className"</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">'foo'</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">"org.apache.sling.engine.impl.SlingMainServlet"</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">'.'</span><span class="o">,</span><span class="s1">'/'</span><span class="o">)+</span><span class="s2">".class"</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">-></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">"Following bundles have the class"</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">¶</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> |