
rt.pipeline.pipe.PipeContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rts-pipeline Show documentation
Show all versions of rts-pipeline Show documentation
Framework to build reactive services for reactive application front-ends
The newest version!
package rt.pipeline.pipe;
import com.google.common.base.Objects;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Pure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rt.async.pubsub.IMessageBus;
import rt.async.pubsub.Message;
import rt.pipeline.IComponent;
import rt.pipeline.UserInfo;
import rt.pipeline.pipe.PipeResource;
import rt.pipeline.pipe.Pipeline;
@SuppressWarnings("all")
public class PipeContext {
private final static Logger logger = LoggerFactory.getLogger("PIPELINE");
@Accessors
private final Message message;
@Accessors
private final PipeResource resource;
private boolean inFail = false;
private final Pipeline pipeline;
private final Iterator iter;
private final HashMap, Object> objects = new HashMap, Object>();
public IMessageBus bus() {
return this.pipeline.getMb();
}
public Object object(final Class> type, final Object instance) {
return this.objects.put(type, instance);
}
public T object(final Class type) {
Object _get = this.objects.get(type);
return ((T) _get);
}
PipeContext(final Pipeline pipeline, final PipeResource resource, final Message message, final Iterator iter) {
this.pipeline = pipeline;
this.resource = resource;
this.message = message;
this.iter = iter;
}
/**
* Sends the context to the delivery destination. Normally this methods is called in the end of the pipeline process.
* So most of the time there is no need to call this.
*/
public void deliver() {
if ((!this.inFail)) {
try {
boolean _equals = Objects.equal(this.message.typ, Message.REPLY);
if (_equals) {
this.deliverReply();
} else {
this.deliverRequest();
}
} catch (final Throwable _t) {
if (_t instanceof RuntimeException) {
final RuntimeException ex = (RuntimeException)_t;
ex.printStackTrace();
boolean _notEquals = (!Objects.equal(this.message.typ, Message.PUBLISH));
if (_notEquals) {
this.fail(ex);
}
} else {
throw Exceptions.sneakyThrow(_t);
}
}
}
}
/**
* Used by interceptors, order the pipeline to execute the next interceptor. If no other interceptor exits, a delivery is proceed.
*/
public void next() {
if ((!this.inFail)) {
boolean _hasNext = this.iter.hasNext();
if (_hasNext) {
try {
IComponent _next = this.iter.next();
_next.apply(this);
} catch (final Throwable _t) {
if (_t instanceof RuntimeException) {
final RuntimeException ex = (RuntimeException)_t;
ex.printStackTrace();
this.fail(ex);
} else {
throw Exceptions.sneakyThrow(_t);
}
}
} else {
this.deliver();
}
}
}
/**
* Send a message to the client resource
* @param msg Should be a new message to send
*/
public void send(final Message msg) {
if ((!this.inFail)) {
this.resource.send(msg);
}
}
/**
* Interrupts the pipeline flow and sends an error message back to the original "from". After this, other calls to "next()" or "fail(..)" are useless.
* @param from The address that will be on reply "header.from".
* @param error The error descriptor message.
*/
public void fail(final Throwable ex) {
if ((!this.inFail)) {
this.replyError(ex);
this.pipeline.fail(ex);
this.inFail = true;
}
}
/**
* Does nothing to the pipeline flow and sends a reply back.
* @param reply Should be a new PipeMessage
*/
public void reply(final Message reply) {
if ((!this.inFail)) {
final Procedure1 _function = (Message it) -> {
it.id = this.message.id;
it.clt = this.message.clt;
it.typ = Message.REPLY;
};
ObjectExtensions.operator_doubleArrow(reply, _function);
this.resource.send(reply);
}
}
/**
* Does nothing to the pipeline flow and sends a OK reply back with a pre formatted JSON schema.
*/
public void replyOK() {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_OK;
};
final Message reply = ObjectExtensions.operator_doubleArrow(_message, _function);
this.reply(reply);
}
}
/**
* Does nothing to the pipeline flow and sends a OK reply back with a pre formatted JSON schema.
* @param value The address that will be on "from".
*/
public void replyOK(final Object resultObj) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_OK;
it.setResult(resultObj);
};
final Message reply = ObjectExtensions.operator_doubleArrow(_message, _function);
this.reply(reply);
}
}
public void replyObservable(final String uuid) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_OBSERVABLE;
it.setResult(("evt:" + uuid));
};
final Message reply = ObjectExtensions.operator_doubleArrow(_message, _function);
this.reply(reply);
}
}
/**
* Does nothing to the pipeline flow and sends a ERROR reply back with a pre formatted JSON schema.
* @param value The error descriptor message.
*/
public void replyError(final Throwable ex) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_ERROR;
it.setResult(ex);
};
final Message reply = ObjectExtensions.operator_doubleArrow(_message, _function);
PipeContext.logger.error("REPLY-ERROR {}", ex);
this.reply(reply);
}
}
public void publish(final Message pub) {
if ((!this.inFail)) {
final Procedure1 _function = (Message it) -> {
it.clt = this.message.clt;
it.typ = Message.PUBLISH;
};
ObjectExtensions.operator_doubleArrow(pub, _function);
this.resource.send(pub);
}
}
public void publishNext(final String uuid, final Object resultObj) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_OK;
it.path = ("evt:" + uuid);
it.setResult(resultObj);
};
final Message pub = ObjectExtensions.operator_doubleArrow(_message, _function);
this.publish(pub);
}
}
public void publishComplete(final String uuid) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_COMPLETE;
it.path = ("evt:" + uuid);
};
final Message pub = ObjectExtensions.operator_doubleArrow(_message, _function);
this.publish(pub);
}
}
public void publishError(final String uuid, final Throwable ex) {
if ((!this.inFail)) {
Message _message = new Message();
final Procedure1 _function = (Message it) -> {
it.cmd = Message.CMD_ERROR;
it.path = ("evt:" + uuid);
it.setResult(ex);
};
final Message pub = ObjectExtensions.operator_doubleArrow(_message, _function);
this.publish(pub);
}
}
/**
* Order the underlying resource channel to disconnect. But the client can be configured to reconnect, so most of the times a reconnection is made by the client.
* To avoid this, the method should only be used when the client orders the disconnection.
*/
public void disconnect() {
this.resource.disconnect();
}
private void deliverRequest() {
final UserInfo user = this.object(UserInfo.class);
boolean _isAuthorized = this.pipeline.isAuthorized(this.message, user);
boolean _not = (!_isAuthorized);
if (_not) {
PipeContext.logger.error("Authorization failed on {}", this.message.path);
RuntimeException _runtimeException = new RuntimeException("Unauthorized user!");
this.fail(_runtimeException);
return;
}
final IComponent srv = this.pipeline.getComponent(this.message.path);
boolean _notEquals = (!Objects.equal(srv, null));
if (_notEquals) {
PipeContext.logger.debug("DELIVER {}", this.message.path);
srv.apply(this);
} else {
PipeContext.logger.info("PUBLISH {}", this.message.path);
IMessageBus _mb = this.pipeline.getMb();
_mb.publish(this.message.path, this.message);
}
}
private void deliverReply() {
PipeContext.logger.debug("DELIVER-REPLY {} {}", this.message.clt, this.message.id);
IMessageBus _mb = this.pipeline.getMb();
_mb.reply(this.message);
}
@Pure
public Message getMessage() {
return this.message;
}
@Pure
public PipeResource getResource() {
return this.resource;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy