@Override public void onDeliverRequest(PublishRequest req) { try { // // TODO remove 4 lines below - just for debug // byte[] details = req.getMessage(); // if (req.getEventType() == 1413) { // System.out.println("zzz"); // } JCsyncAbstractOperation op = JCsyncAbstractOperation.encode(req.getMessage()); op.setReqestID(req.getTransactionID()); log.trace( this.pubsubLayer.getNodeInfo().getName() + " (onDeliverRequest) - [publisher]:" + req.getPublisher() + ", [node relay]:" + req.getSourceInfo() + ": " + op); if (this.checkIfAlreadyReceived(req)) { log.trace( this.pubsubLayer.getNodeInfo().getName() + " (onDeliverRequest): - received request that was aready received, skipping ... : " + op); return; } // check that this node can hold this request JCSyncAbstractSharedObject so = this.sharedObjects.get(op.getObjectID()); if (so != null) { if ((op.getOperationType() & OP_REQ_GENERIC) == OP_REQ_GENERIC) { if (op.getOperationType() == OP_REQ_TRANSFER_OBJECT) { // there is no need to inform consistency manager about this kind of request, just send // response and indication sendResponse(req, PubSubConstants.RESP_SUCCESS); synchronized (so.operationIdIncrementLocker) { log.trace( getNodeInfo().getName() + ": transferring shared object with current operation id: " + so.getCurrentOperationID() + ", to node: " + req.getPublisher()); JCsyncAbstractOperation op_ = JCsyncAbstractOperation.get_OP_IND_TRANSFER_OBJECT( op.getObjectID(), so.encode(), req.getPublisher()); op_.setReqestID(op.getReqestID()); sendMessage(req, op_, false); } } else { // if this node is a root if (getAssignedTopic(req.getTopicID()) .isTopicRoot(this.pubsubLayer.getNodeInfo().getID())) { AbstractConsistencyManager acm = getConsistencyManager(req.getTopicID()); if (acm != null) { log.trace( "(onDeliverRequest) - passing operation to consistency model: " + op.toString()); acm.requestReceived(req, op); } else { log.fatal( "(onDeliverRequest) - there is no registered consistency manager for this operation: " + op.toString()); } } else { log.trace( "(onDeliverRequest) - forwarding operation request to the parent node: " + op.toString()); this.pubsubLayer.forwardToParent(req, getAssignedTopic(req.getTopicID())); } } } else { log.fatal("(onDeliverRequest) - unhandled operation type: " + op.toString()); } } else { if (op.getOperationType() == OP_REQ_TRANSFER_OBJECT) { log.trace( getNodeInfo().getName() + ": (onDeliverRequest) - shared object not found!: " + op.toString() + ", forwarding request to the topic owner: " + op.toString()); this.pubsubLayer.forwardToOtherNode( req, this.pubsubLayer.getTopic(op.getObjectID()).getOwner().getNodeInfo()); } else { log.fatal( getNodeInfo().getName() + ": (onDeliverRequest) - shared object not found!: " + op.toString()); sendResponse(req, PubSubConstants.RESP_DOESNOTEXIST); } } } catch (Exception e) { log.error("An error occurred:", e); } }
@Override public void onDeliverPubSubResponse( String name, short operationType, short respCode, long reqID) { log.trace( this.pubsubLayer.getNodeInfo().getName() + ": (onDeliverPubSubResponse) , topicName: " + name + ", operationType: " + operationType + ", respCode: " + respCode + ",reqID: " + reqID); short rCode = respCode; // mapping respCode - in the PubSub sometimes calls respCodes from PubSUbConstants and sometimes // from NodeError if (respCode == NodeError.AUTHERR) { rCode = PubSubConstants.RESP_FORBIDDEN; } else if (respCode == NodeError.NOSUCHTOPICERR) { rCode = PubSubConstants.RESP_DOESNOTEXIST; } respCode = rCode; // mapping pubsub respCodes to jcsync resp codes if (respCode == PubSubConstants.RESP_SUCCESS) { rCode = JCSyncConstans.J_RESP_GENERAL_SUCCESS; } else if (respCode == PubSubConstants.RESP_ALREADYEXISTS) { rCode = JCSyncConstans.J_ERR_COLLECTION_EXISTS; } else if (respCode == PubSubConstants.RESP_DOESNOTEXIST) { rCode = JCSyncConstans.J_ERR_OBJECT_NOT_EXISTS; } else if (respCode == PubSubConstants.RESP_FORBIDDEN) { rCode = JCSyncConstans.J_ERR_COLLECTION_AUTH_ERROR; } respCode = rCode; try { /* sometimes response is already received, but the locker is not * properly initialized in the consistency manager - if * the request is sending then wait for the end of it. * */ this.request_response_locker.readLock().lock(); if ((operationType & OP_GENERIC_JCSYNC_OPERATION) == OP_GENERIC_JCSYNC_OPERATION) { JCsyncAbstractOperation o = null; // JCsyncAbstractOperation.getByType(operationType, name); o = JCsyncAbstractOperation.getByType(operationType, name, this.getNodeInfo().getName()); o.setReqestID(reqID); if (getConsistencyManager(name) != null) { getConsistencyManager(name).responseReceived(o, respCode); } else { this.dcManager.responseReceived(o, respCode); } return; } switch (operationType) { case PubSubConstants.MSG_CREATETOPIC: { JCsyncAbstractOperation o = null; o = JCsyncAbstractOperation.get_OP_REQ_CREATE_SHARED_OBJECT( name, this.getNodeInfo().getName()); this.dcManager.responseReceived(o, respCode); return; } case PubSubConstants.MSG_SUBSCRIBE: { JCsyncAbstractOperation o = null; o = JCsyncAbstractOperation.get_OP_REQ_SUBSCRIBE(name, this.getNodeInfo().getName()); this.dcManager.responseReceived(o, respCode); return; } case PubSubConstants.MSG_UNSUBSCRIBE: { JCsyncAbstractOperation o = null; o = JCsyncAbstractOperation.get_OP_REQ_UNSUBSCRIBE(name, this.getNodeInfo().getName()); this.dcManager.responseReceived(o, respCode); return; } case PubSubConstants.EVENT_REMOVETOPIC: { JCsyncAbstractOperation o = null; o = JCsyncAbstractOperation.get_OP_REQ_REMOVE(name, this.getNodeInfo().getName()); this.dcManager.responseReceived(o, respCode); return; } default: { log.fatal( "Received unsuported response code: " + respCode + ", for operation: " + operationType + ", for shared object name: " + name); } } } catch (Exception ex) { log.error("An error while processing (onDeliverPubSubResponse)", ex); } finally { this.request_response_locker.readLock().unlock(); } }
/** * Sends operation as a pub-sub message thought overlay. If the <tt>blocking</tt> value is * <tt>true</tt> then working thread will be suspended until the response and indication (if * required) will be received from the overlay, if <tt>blocking</tt> value is <tt>false</tt> then * working thread will not be suspended and method returns <tt>null</tt>.<br> * Typically used to sends requests. * * @param op operation that will be send * @param blocking determines whenever the calling thread will be suspended until the results of * given operation will be received. * @return the results of given operation or <tt>null</tt> if the blocking argument value is set * to <tt>false</tt> * @throws Exception any error which was occurred during this operation */ @Override public Object sendMessage(JCsyncAbstractOperation op, boolean blocking) throws Exception { // if the topic for this object is unknown then throw new exception try { this.request_response_locker.writeLock().lock(); if (getAssignedTopic(op.getObjectID()) == null) { throw ObjectNotExistsException.instance(); } // try to get the consistency manager if there is already selected AbstractConsistencyManager acm = getConsistencyManager(op.getObjectID()); if (acm == null) { acm = this.dcManager; } short type = op.getOperationType(); if ((type & OP_REQ_GENERIC) == OP_REQ_GENERIC) { acm.beforeRequestSend(op, blocking); this.pubsubLayer.getCustomAlgorith().registerSharedObjectName(op.getObjectID()); Transaction t = this.pubsubLayer .getCustomAlgorith() .nextPublishTransaction(op.getObjectID(), op.getOperationType()); op.setReqestID(t.getID()); log.trace( "(sendMessage) - operation sent (blocking=[" + blocking + "]) operation: " + op.toString()); this.messagesToSend.put(new MessageToSend(op, t)); this.request_response_locker.writeLock().unlock(); Object result = acm.afterRequestSend(op, blocking); return result; } else if ((type & OP_INDICATION_GENERIC) == OP_INDICATION_GENERIC) { acm.beforeRequestSend(op, blocking); this.pubsubLayer.getCustomAlgorith().registerSharedObjectName(op.getObjectID()); Transaction t = this.pubsubLayer .getCustomAlgorith() .nextPublishTransaction(op.getObjectID(), op.getOperationType()); op.setReqestID(t.getID()); log.trace( "(sendMessage) - operation sent (blocking=[" + blocking + "]) operation: " + op.toString()); this.messagesToSend.put(new MessageToSend(op, t)); this.request_response_locker.writeLock().unlock(); Object result = acm.afterRequestSend(op, blocking); return result; } else { log.error("Unhandled operation type: " + op.toString()); } } catch (Exception e) { throw e; } finally { if (this.request_response_locker.writeLock().getHoldCount() > 0 && this.request_response_locker.writeLock().isHeldByCurrentThread()) { this.request_response_locker.writeLock().unlock(); } } return null; }