blob: 9f963f9fe1335fe9776adab348a14c2726a90fe6 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="keywords" content="extensionsdev-docs, framework, plugin, extension, json rpc, communication, events, subscribe">
<title>Communication: JSON-RPC | Eclipse Che Documentation</title>
<link rel="stylesheet" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous">
<!--<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">-->
<link rel="stylesheet" href="css/modern-business.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="css/customstyles.css">
<link rel="stylesheet" href="css/boxshadowproperties.css">
<!-- most color styles are extracted out to here -->
<link rel="stylesheet" href="css/theme-che.css">
<link rel="stylesheet" href="/css/coderay.css" media="screen" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js" crossorigin="anonymous"></script>
<script src="js/jquery.navgoco.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- Anchor.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script>
<script src="js/toc.js"></script>
<script src="js/customscripts.js"></script>
<link rel="shortcut icon" href="che/docs/images/favicon.ico">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="alternate" type="application/rss+xml" title="che" href="http://0.0.0.0:4000/feed.xml">
<script>
$(document).ready(function() {
// Initialize navgoco with default options
$("#mysidebar").navgoco({
caretHtml: '',
accordion: true,
openClass: 'active', // open
save: false, // leave false or nav highlighting doesn't work right
cookie: {
name: 'navgoco',
expires: false,
path: '/'
},
slide: {
duration: 400,
easing: 'swing'
}
});
$("#collapseAll").click(function(e) {
e.preventDefault();
$("#mysidebar").navgoco('toggle', false);
});
$("#expandAll").click(function(e) {
e.preventDefault();
$("#mysidebar").navgoco('toggle', true);
});
});
</script>
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
</script>
<script>
$(document).ready(function() {
$("#tg-sb-link").click(function() {
$("#tg-sb-sidebar").toggle();
$("#tg-sb-content").toggleClass('col-md-9');
$("#tg-sb-content").toggleClass('col-md-12');
$("#tg-sb-icon").toggleClass('fa-toggle-on');
$("#tg-sb-icon").toggleClass('fa-toggle-off');
});
});
</script>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container topnavlinks">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="fa fa-home fa-lg navbar-brand" href="index.html">&nbsp;<span class="projectTitle"> Eclipse Che Documentation</span></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<!-- toggle sidebar button -->
<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>
<!-- entries without drop-downs appear here -->
<li><a href="https://medium.com/eclipse-che-blog/" target="_blank">Blog</a></li>
<li><a href="https://github.com/eclipse/che" target="_blank">Source Code</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Support<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://github.com/eclipse/che/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Akind%2Fbug" target="_blank">Known Bugs</a></li>
<li><a href="https://github.com/eclipse/che/issues/new" target="_blank">File an Issue</a></li>
<li><a href="https://stackoverflow.com/questions/tagged/eclipse-che" target="_blank">Che on StackOverflow</a></li>
</ul>
</li>
<!--
<li>
<a class="email" title="Submit feedback" href="#" onclick="javascript:window.location='mailto:?subject= feedback&body=I have some feedback about the Communication: JSON-RPC page: ' + window.location.href;"><i class="fa fa-envelope-o"></i> Feedback</a>
</li>
-->
<!--comment out this block if you want to hide search-->
<li>
<!--start search-->
<div id="search-demo-container">
<input type="text" id="search-input" placeholder="search...">
<ul id="results-container"></ul>
</div>
<script src="js/jekyll-search.js" type="text/javascript"></script>
<script type="text/javascript">
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
dataSource: 'search.json',
searchResultTemplate: '<li><a href="{url}" title="Communication: JSON-RPC">{title}</a></li>',
noResultsText: 'No results found.',
limit: 10,
fuzzy: true,
})
</script>
<!--end search-->
</li>
</ul>
</div>
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<div class="container">
<div id="main">
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle"> </li>
<li>
<a href="#">Overview</a>
<ul>
<li><a href="index.html">Introduction</a></li>
<li><a href="quick-start.html">Getting Started</a></li>
<li><a href="single-multi-user.html">Single and Multi-User Flavors</a></li>
<li><a href="infra-support.html">Supported Infrastructures</a></li>
</ul>
</li>
<li>
<a href="#">Che on Docker</a>
<ul>
<li><a href="docker-single-user.html">Docker - Single User</a></li>
<li><a href="docker-multi-user.html">Docker - Multi User</a></li>
<li><a href="docker-config.html">Docker - Configuration</a></li>
<li><a href="docker-cli.html">Docker - CLI Reference</a></li>
</ul>
</li>
<li>
<a href="#">Che on Kubernetes</a>
<ul>
<li><a href="kubernetes-single-user.html">Kubernetes - Single User</a></li>
<li><a href="kubernetes-multi-user.html">Kubernetes - Multi User</a></li>
<li><a href="kubernetes-config.html">Kubernetes - Configuration</a></li>
<li><a href="kubernetes-admin-guide.html">Kubernetes - Admin Guide</a></li>
</ul>
</li>
<li>
<a href="#">Che on OpenShift</a>
<ul>
<li><a href="openshift-single-user.html">OpenShift - Single User</a></li>
<li><a href="openshift-multi-user.html">OpenShift - Multi User</a></li>
<li><a href="openshift-config.html">OpenShift - Configuration</a></li>
<li><a href="openshift-admin-guide.html">OpenShift - Admin Guide</a></li>
</ul>
</li>
<li>
<a href="#">User Management</a>
<ul>
<li><a href="user-management.html">Authentication and Authorization</a></li>
<li><a href="authentication.html">Security Model</a></li>
<li><a href="permissions.html">Permissions</a></li>
<li><a href="organizations.html">Organizations in UD</a></li>
<li><a href="resource-management.html">Resource Management</a></li>
</ul>
</li>
<li>
<a href="#">User Guides</a>
<ul>
<li><a href="creating-starting-workspaces.html">Creating and starting Workspaces</a></li>
<li><a href="ide-projects.html">Projects</a></li>
<li><a href="editor-code-assistance.html">Editor and Code-Assistance</a></li>
<li><a href="dependency-management.html">Dependency Management</a></li>
<li><a href="commands-ide-macro.html">Commands and IDE Macros</a></li>
<li><a href="version-control.html">Version Control</a></li>
<li><a href="debug.html">Debug</a></li>
</ul>
</li>
<li>
<a href="#">Workspace Administration</a>
<ul>
<li><a href="what-are-workspaces.html">Workspace Overview</a></li>
<li><a href="stacks.html">Workspace - Stacks</a></li>
<li><a href="recipes.html">Workspace - Recipes</a></li>
<li><a href="servers.html">Workspace - Servers</a></li>
<li><a href="installers.html">Workspace - Installers</a></li>
<li><a href="volumes.html">Workspace - Volumes Mount</a></li>
<li><a href="env-variables.html">Workspace - Environment Variables</a></li>
<li><a href="projects.html">Workspace - Projects</a></li>
<li><a href="workspaces-troubleshooting.html">Workspace - Troubleshooting</a></li>
<li><a href="workspace-data-model.html">Workspace Data Model</a></li>
</ul>
</li>
<li>
<a href="#">Portable Workspaces</a>
<ul>
<li><a href="chedir-getting-started.html">Chedir - Getting Started</a></li>
<li><a href="why-chedir.html">Chedir - Why Chedir?</a></li>
<li><a href="chedir-installation.html">Chedir - Installation</a></li>
<li><a href="chedir-project-setup.html">Chedir - Project Setup</a></li>
<li><a href="chedir-up-and-down.html">Chedir - Up and Down</a></li>
<li><a href="chefile.html">Chedir - Chefile</a></li>
<li><a href="chedir-ssh.html">Chedir - SSH</a></li>
<li><a href="factories-getting-started.html">Factory - Getting Started</a></li>
<li><a href="creating-factories.html">Factory - Creating</a></li>
<li><a href="factories_json_reference.html">Factory - JSON Reference</a></li>
</ul>
</li>
<li>
<a href="#">Developer Guides</a>
<ul>
<li><a href="framework-overview.html">Overview</a></li>
<li><a href="rest-api.html">SDK - REST API</a></li>
<li><a href="che-in-che-quickstart.html">SDK - Your First Plugin</a></li>
<li><a href="build-reqs.html">SDK - Building Che</a></li>
<li><a href="assemblies.html">SDK - Assemblies</a></li>
<li><a href="logging.html">SDK - Logging</a></li>
<li><a href="ide-extensions-gwt.html">SDK - GWT IDE Extensions</a></li>
<li><a href="server-side-extensions.html">SDK - Server Side Extensions</a></li>
<li><a href="custom-installers.html">SDK - Installers</a></li>
<li><a href="project-types.html">SDK - Project Types</a></li>
<li><a href="language-servers.html">SDK - Language Support</a></li>
<li><a href="parts.html">IDE UI&#58 Parts</a></li>
<li><a href="actions.html">IDE UI&#58 Actions</a></li>
</ul>
</li>
<li>
<a href="#">Dev Essentials</a>
<ul>
<li><a href="guice.html">Dependency Injection</a></li>
<li><a href="dto.html">Transport&#58 DTO</a></li>
<li class="active"><a href="json-rpc.html">Communication&#58 JSON-RPC</a></li>
<li><a href="handling-projects-in-plugins.html">Handling Projects in Plugins</a></li>
<li><a href="dao.html">Persistence, DAO</a></li>
<li><a href="properties.html">Properties</a></li>
</ul>
</li>
<li>
<a href="#">Infrastructure and SPI</a>
<ul>
<li><a href="spi_overview.html">Overview</a></li>
<li><a href="spi-implementation.html">Implementation Notes</a></li>
</ul>
</li>
<!-- if you aren't using the accordion, uncomment this block:
<p class="external">
<a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a>
</p>
-->
</ul>
<!-- this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
<script>$("li.active").parents('li').toggleClass("active");</script>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<div class="post-header">
<h1 class="post-title-main">Communication: JSON-RPC</h1>
</div>
<div class="post-content">
<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
<script>
$( document ).ready(function() {
// Handler for .ready() called.
$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2' });
/* this offset helps account for the space taken up by the floating toolbar. */
$('#toc').on('click', 'a', function() {
var target = $(this.getAttribute('href'))
, scroll_target = target.offset().top
$(window).scrollTop(scroll_target - 10);
return false
})
});
</script>
<div id="toc"></div>
<!--
-->
<div class="sect1">
<h2 id="overview">Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In CHE we use <a href="http://www.jsonrpc.org/specification">JSON-RPC</a> for asynchronous communication between clients and servers. JSON-RPC is asymmetric by nature so in order to be able to information independently we use duplex approach where both sides (clients and servers) can act both as a JSON-RPC server and as JSON-RPC client. To make it clear, clients (e.g. IDE) can send JSON-RPC requests (acting as JSON-RPC client) and receive requests (acting as JSON-RPC server) and servers (e.g. workspace master or workspace agent) can do the same.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="send-a-json-rpc-request">Send a JSON-RPC request</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To send request you can use <a href="https://github.com/eclipse/che/blob/master/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/commons/RequestTransmitter.java"><code>org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter</code></a>, the most basic use case (actual for both client and server sides) looks quite simple:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">transmitter
.newRequest()
.endpointId(endpointId)
.methodName(method)
.paramsAsDto(dto)
.sendAndReceiveResultAsDto(dtoClass)
.onSuccess((result) -&gt; {})
.onFailure((jsonRpcError) -&gt; {});</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>endpointId</strong> - in common sense can be an arbitrary <strong><code>String</code></strong> identifier that allows to distinguish endpoints. Please note that for server sides these endpoints are statically defined as constants: <code>"ws-agent"</code> for workspace agent and <code>"ws-master"</code> for workspace master for example, while for clients it is a dynamic identifier because clients are dynamic by their nature.</p>
</div>
<div class="paragraph">
<p><strong>method</strong> - method name corresponds to it’s definition in JSON-RPC protocol specification. In Che we use the following naming convention: method name in most cases consists of two parts separated be slash - scope and action. For example <code>project/create</code> where <code>project</code> is the scope and <code>create</code> is the action.</p>
</div>
<div class="paragraph">
<p><strong>dto</strong> - value of parameters passed (in our example it is a <a href="https://en.wikipedia.org/wiki/Data_transfer_object">DTO</a>), please note that though JSON-RPC protocol specification requires parameters either as json objects or arrays, you can use single primitives here as well and they will be automatically converted to a singleton array.</p>
</div>
<div class="paragraph">
<p><strong>dtoClass</strong> - class of a result that will be contained within the response to our request</p>
</div>
<div class="paragraph">
<p><strong>result</strong> - result of our request (in our example it is of class <strong>dtoClass</strong>)</p>
</div>
<div class="paragraph">
<p><strong>jsonRpcError</strong> - error object that contains information about the error if any happened, its structure corresponds to error defined in JSON-RPC protocol specification</p>
</div>
<div class="paragraph">
<p>Source code example of using of the transmitter can be found here: <a href="https://github.com/eclipse/che/blob/master/wsagent/che-core-api-debug/src/main/java/org/eclipse/che/api/debugger/server/DebuggerJsonRpcMessenger.java#L76" class="bare">https://github.com/eclipse/che/blob/master/wsagent/che-core-api-debug/src/main/java/org/eclipse/che/api/debugger/server/DebuggerJsonRpcMessenger.java#L76</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="receive-a-json-rpc-request">Receive a JSON-RPC request</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To receive a request you can use <a href="https://github.com/eclipse/che/blob/master/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/commons/RequestHandlerConfigurator.java"><code>org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator</code></a>, the use case (actual for both sides):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">configurator
.newConfiguration()
.methodName(method)
.paramsAsDto(paramsDtoClass)
.resultAsDto(resultDtoClass)
.withFunction((endpointId, paramsDto) -&gt; resultDto);</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>method</strong> - the name of JSON-RPC method that is to be handled by this configuration</p>
</div>
<div class="paragraph">
<p><strong>paramsDtoClass</strong> - class of parameters that are passed in a JSON-RPC request (in our example it is a DTO)</p>
</div>
<div class="paragraph">
<p><strong>resultDtoClass</strong> - class of result that is passed in a JSON-RPC response (in our example it is DTO)</p>
</div>
<div class="paragraph">
<p><strong>endpointId</strong> - the identifier of an endpoint that sends the request that is handled by this configuration</p>
</div>
<div class="paragraph">
<p><strong>paramsDto</strong> - the value of parameters passed</p>
</div>
<div class="paragraph">
<p><strong>resultDto</strong> - the value of result passed</p>
</div>
<div class="paragraph">
<p>Source code example of using of the transmitter can be found here: <a href="https://github.com/eclipse/che/blob/master/wsagent/che-core-api-debug/src/main/java/org/eclipse/che/api/debugger/server/DebuggerJsonRpcMessenger.java#L117" class="bare">https://github.com/eclipse/che/blob/master/wsagent/che-core-api-debug/src/main/java/org/eclipse/che/api/debugger/server/DebuggerJsonRpcMessenger.java#L117</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="client-endpoint-identification">Client endpoint identification</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In order to receive a cross sessional identifier clients (e.g. IDE) can use a <a href="https://github.com/eclipse/che/blob/master/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/websocket/impl/WebsocketIdService.java"><code>org.eclipse.che.api.core.websocket.impl.WebsocketIdService</code></a>, otherwise client identifier will not be persisted between websocket sessions. The most common use case (client specific):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">requestTransmitter
.newRequest()
.endpointId(<span class="string"><span class="delimiter">&quot;</span><span class="content">ws-master</span><span class="delimiter">&quot;</span></span>)
.methodName(<span class="string"><span class="delimiter">&quot;</span><span class="content">websocketIdService/getId</span><span class="delimiter">&quot;</span></span>)
.noParams()
.sendAndReceiveResultAsString()
.onSuccess(appContext::setApplicationWebsocketId);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Source code example of using websocket identification service can be found here: <a href="https://github.com/eclipse/che/blob/master/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/jsonrpc/WsMasterJsonRpcInitializer.java#L134" class="bare">https://github.com/eclipse/che/blob/master/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/jsonrpc/WsMasterJsonRpcInitializer.java#L134</a></p>
</div>
</div>
</div>
<div class="tags">
<b>Tags: </b>
<a href="tag_extensions.html" class="btn btn-default navbar-btn cursorNorm" role="button">extensions</a>
<a href="tag_dev-docs.html" class="btn btn-default navbar-btn cursorNorm" role="button">dev-docs</a>
</div>
<!--
-->
</div>
<hr class="shaded"/>
<footer>
<div class="row">
<div class="col-lg-12 footer">
Eclipse Che - Documentation <br/>
Site last generated: Sep 13, 2018 <br/>
<hr>
<a href="http://www.eclipse.org" target="_blank">Eclipse Foundation</a><br/>
<a href="http://www.eclipse.org/legal/privacy.php" target="_blank">Privacy Policy</a><br/>
<a href="http://www.eclipse.org/legal/termsofuse.php" target="_blank">Terms of Use</a><br/>
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">Eclipse Public License</a><br/>
<a href="http://www.eclipse.org/legal" target="_blank">Legal Resources</a><br/>
</div>
</div>
</footer>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- /#main -->
</div>
</body>
</html>