Kraken RPC
In closed/secured network environment, or NAT'ed network, you generally cannot connect to client. Kraken RPC enables bi-direction RPC invocation in these environments. Since RPC connection works just as a transport, you can create RPC session to either direction (client to server, or server to client) as long as RPC service is bound to that connection.
For example, Let's imagine that Kraken Sentry connects to Kraken Base over the public internet. Kraken Sentry is installed in the NAT'ed network. Even in this network configuration, Kraken Base can connect RPC session to RPC services which provided by Kraken Sentry.
Moreover, Kraken RPC provides declarative service programming. See calculator service and client example.
Author
Commands
Access Control
rpc.guid
Print GUID of local RPC agent:
kraken@Future bin> rpc.guid ae6d2925-24de-400b-8f04-9bfa31f8876f
You can grant access privilege to other RPC clients based on GUID.
rpc.registerPeer
Register new peer RPC agent:
kraken@Future bin> rpc.registerPeer
Description
register rpc peer
Arguments
1. guid: the guid of peer (required)
2. password: the password of peer (required)
3. trust level: 1(untrust), 2(low), 3(medium), 4(high) (required)
kraken@Future bin> rpc.registerPeer test-guid PASSWORD 4
test-guid registered
You should set password for non-SSL channel. For now, SSL channel do not use password for peering.
rpc.unregisterPeer
kraken@Future bin> rpc.unregisterPeer
Description
unregister rpc peer
Arguments
1. guid: peer's guid (required)
kraken@Future bin> rpc.unregisterPeer test-guid
test-guid unregistered
rpc.peers
Print all registered RPC peers:
kraken@Future bin> rpc.peers RPC Peers -------------- test-guid
Connection & Session
Manage RPC port binding, connections, and sessions.
rpc.connections
Print all current RPC connections (inbound and outbound):
kraken@Future bin> rpc.connections RPC Connections ---------------- id=4084687, peer=(b6b648b7-4605-4b20-be40-3d4778a58fdb, /127.0.0.1:54291), trusted level=High, ssl=true
In this example, "b6b648b7-4605-4b20-be40-3d4778a58fdb" is a peer GUID. /127.0.0.1:54291 is a remote address. "ssl=true" means SSL connection.
rpc.setprop
rpc.sessions
Print all RPC sessions over the RPC connection:
kraken@Future bin> rpc.sessions
Description
list all sessions of the connection
Arguments
1. cid: connection id (required)
kraken@Future bin> rpc.sessions 4084687
RPC Sessions
---------------
id=0, service=rpc-control, peer=/127.0.0.1:54291
All connections have rpc-control session by default.
rpc.services
Print all bound RPC service on the connection:
kraken@Future bin> rpc.services
Description
list all bound services
Arguments
1. cid: connection id (required)
kraken@Future bin> rpc.services 4084687
Service Bindings
-------------------
name=logdb, class=org.krakenapps.logdb.impl.LogRpcService
name=rpc-control, class=org.krakenapps.rpc.impl.RpcControlService
name=logdb-mapreduce, class=org.krakenapps.logdb.impl.MapReduceRpcService
RPC client can create new RPC session for RPC service.
rpc.bindings
Print all listen port bindings:
kraken@Future bin> rpc.bindings Port Bindings --------------- addr=0.0.0.0, port=7140, key=rpc-agent, trust=rpc-ca]
No RPC port will be opened by default. You should open new RPC port yourself. Use rpc.open or rpc.openSsl command to open new listening port.
rpc.open
kraken@Future bin> rpc.open
Description
open rpc port
Arguments
1. port: rpc port (required)
2. ip: bind address. '0.0.0.0' by default (optional)
Open cleartext RPC port. default bind address is '0.0.0.0'.
rpc.openSsl
kraken@Future bin> rpc.openSsl
Description
open rpc ssl port
Arguments
1. port: rpc listening port for ssl (required)
2. key alias: key alias. use 'keystore.list' command to list all registered key aliases. Keystore should contain public and private key pair. e.g. PKCS12 keystore (required)
3. trust alias: trust alias. use 'keystore.list' command to list all registered key aliases. Trusted keystore should contain public key of certificate authority (required)
4. ip: bind address. '0.0.0.0' by default (optional)
Use registered keystore aliases for SSL port bindings.
rpc.close
kraken@Future bin> rpc.close
Description
close rpc port or rpc ssl port
Arguments
1. port: rpc port or rpc ssl port (required)
2. ip: bind address. '0.0.0.0' by default (optional)
rpc.connect
rpc.connectSsl
rpc.disconnect
rpc.disconnectAll
rpc.requestPeering
Blocking Call
rpc.waitings
kraken@Future bin> rpc.waitings
Description
list all waiting calls of the connection
Arguments
1. cid: connection id (required)
You can figure out current blocking RPC calls. Use 'rpc.cancel' command to cancel blocking RPC call.
rpc.cancel
kraken@Future bin> rpc.cancel
Description
cancel rpc calls of the connection
Arguments
1. cid: connection id (required)
2. call id: call id (required)
rpc.props
Tutorial
Calculator Service
CalculatorService.java
package org.krakenapps.examples.rpc.calc;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.ServiceProperty;
import org.krakenapps.rpc.RpcMethod;
import org.krakenapps.rpc.SimpleRpcService;
@Component(name = "calc-service")
@Provides
public class CalculatorService extends SimpleRpcService {
@SuppressWarnings("unused")
@ServiceProperty(name = "rpc.name", value = "calc")
private String name;
@RpcMethod(name = "add")
public int add(int a, int b) {
return a + b;
}
}
metadata.xml
<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/CURRENT/core.xsd" xmlns="org.apache.felix.ipojo"> <instance component="calc-service" /> </ipojo>
Calculator Client
RpcConnectionProperties props = new RpcConnectionProperties(remote);
props.setPassword(password);
RpcClient client = new RpcClient(guid);
RpcConnection conn = client.connect(props);
RpcSession session = conn.createSession("calc");
Object value = session.call("add", new Object[] { 100, 200 });
System.out.println(value);
client.close();
Messaging Patterns
You can pass only java primitive types (null, Boolean, Short, Integer, Long, String, Date, InetAddress, Float, Double, byte[]) and collection types (Map<String, Object> or Collection) for arguments. If you want to send user-defined compound types, use PrimitiveConverter to serialize arbitrary user-defined class instance to primitive mixture, or parse primitive mixtures to user-defined class instance. See PrimitiveConverterTest unit test for usage example. However, I DO NOT recommend PrimitiveConverter for high performance scenario. It is somewhat slow because it uses java reflection.
Synchronous (aka blocking) Call
If you want blocking call, use:
Object call(String method, Object... params) throws RpcException, InterruptedException; Object call(String method, Object[] params, long timeout) throws RpcException, InterruptedException;
Asynchronous Call
If you want non-blocking and return value, use:
RpcAsyncResult call(String method, Object[] params, RpcAsyncCallback callback);
Post (aka fire-and-forget)
When you do not require return value, or want just notification, use:
void post(String method, Object... params);
Protocol
Peering
For privileged RPC invocation, each node should be authenticated by the other. To create any RPC session (call session-request of rpc-control session), you should peering first.
Steps
- Each peer set rpc-control for session 0.
- Each peer send peering-request RPC call with guid string argument.
- RpcControlService.handlePeeringRequest will handle peering-request method call.
- If channel uses non-SSL protocol, send reject response with [ "challenge", guid, nonce ]. Nonce is used for password hashing.
- If channel uses SSL protocol, RPC control service try to find peer in peer registry. Registered peer will be granted specified trust level. Non-registered peer will have Low-trust. Then RPC control service send success response with [ "success", guid, trust level ]. (Untrusted 1, Low 2, Medium 3, High 4)
- Each peer handles "success" or "challenge" response:
- For "success" response, peer set trusted level (trusted level by the other) and finishes peering process.
- For "challenge" response, peer call "authenticate" method with [ guid, hash ]. hash is SHA1(password + nonce).
- RpcControlService.handleAuthenticate will handle authenticate method call.
- Calculates hash using nonce and saved password, then matches hash value.
- Sets trust level, and sends challenge result with [ result, trust level ]. result is boolean (true if success), and trust level is between 1-4. (Untrusted 1, Low 2, Medium 3, High 4)
See Also
- Kraken CA - Create X.509 and PKCS12 certificate for SSL RPC channel.
- Kraken Codec - Kraken RPC protocol encodes and decodes payload using Kraken Codec.
- Kraken Sentry and Kraken Base - Kraken RPC is initially designed for bi-direction RPC between agent and SIEM server.
Release History
- 1.5.1
