Destination[] destinationArr = publishQos.getDestinationArr(); // !!! add XPath client query here !!!
Authenticate authenticate = this.requestBroker.getAuthenticate();
//----- Send message to every destination client
for (int ii = 0; ii < destinationArr.length; ii++) {
Destination destination = destinationArr[ii];
if (log.isLoggable(Level.FINE)) log.fine(ME+": Working on PtP message for destination [" + destination.getDestination() + "]");
SessionName destinationSessionName = destination.getDestination();
boolean destinationIsSession = destinationSessionName.isSession();
boolean forceQueing = destination.forceQueuing();
boolean wantsPtP = true; // TODO if destination never has logged in spam would be possible!
SubjectInfo destinationClient = null;
// Handle PtP to subject in a thread safe manner
if (!destinationIsSession) { // -> subject
// 3 + 6 (force queing ignored since same reaction for both)
destinationClient = authenticate.getSubjectInfoByName(destination.getDestination());
if (!forceQueing && destinationClient==null) {
String tmp = ME+": Sending PtP message '" + cacheEntry.getLogId() + "' to '" + destination.getDestination() + "' failed, the destination is unkown, the message rejected.";
//log.warning(tmp); is logged by caller already
throw new XmlBlasterException(serverScope, ErrorCode.USER_PTP_UNKNOWNDESTINATION, ME, tmp +
" Client is not logged in and <destination forceQueuing='true'> is not set");
}
if (log.isLoggable(Level.FINE)) log.fine(ME+": Queuing PtP message '" + cacheEntry.getLogId() + "' for subject destination [" + destination.getDestination() + "], forceQueing="+forceQueing);
// We are responsible to call destinationClient.getLock().release()
final boolean returnLocked = true;
destinationClient = authenticate.getOrCreateSubjectInfoByName(destination.getDestination(), returnLocked, null, null);
try {
MsgQueueUpdateEntry msgEntrySubject = new MsgQueueUpdateEntry(serverScope, cacheEntry,
destinationClient.getSubjectQueue().getStorageId(), destination.getDestination(),
Constants.SUBSCRIPTIONID_PtP, false);
destinationClient.queueMessage(msgEntrySubject);
continue;
}
finally {
destinationClient.getLock().release();
}
}
// Handle PtP to session in a thread safe manner
SessionInfo receiverSessionInfo = null;
try {
receiverSessionInfo = authenticate.getSessionInfo(destination.getDestination());
if (receiverSessionInfo != null) {
receiverSessionInfo.getLock().lock();
//receiverSessionInfo.waitUntilAlive();
if (receiverSessionInfo.isAlive()) {
if (!receiverSessionInfo.getConnectQos().isPtpAllowed() &&
!Constants.EVENT_OID_ERASEDTOPIC.equals(cacheEntry.getKeyOid())) { // no spam, case 2
if (log.isLoggable(Level.FINE)) log.fine(ME+": Rejecting PtP message '" + cacheEntry.getLogId() + "' for destination [" + destination.getDestination() + "], isPtpAllowed=false");
throw new XmlBlasterException(serverScope, ErrorCode.USER_PTP_DENIED, ME,
receiverSessionInfo.getId() + " does not accept PtP messages '" + cacheEntry.getLogId() +
"' is rejected");
}
}
else {
receiverSessionInfo.releaseLockAssertOne("Topic=" + getId());
receiverSessionInfo = null;
}
}
if (receiverSessionInfo == null && !forceQueing) {
String tmp = ME+": Sending PtP message '" + cacheEntry.getLogId() + "' to '" + destination.getDestination() + "' failed, the destination is unkown, the message rejected.";
log.warning(tmp);
throw new XmlBlasterException(serverScope, ErrorCode.USER_PTP_UNKNOWNDESTINATION, ME, tmp +
" Client is not logged in and <destination forceQueuing='true'> is not set");
}
// Row 1 in table
if (receiverSessionInfo == null) { // We create a faked session without password check
if (log.isLoggable(Level.FINE)) log.fine(ME+": Working on PtP message '" + cacheEntry.getLogId() + "' for destination [" + destination.getDestination() + "] which does not exist, forceQueuing=true, we create a dummy session");
ConnectQos connectQos = new ConnectQos(serverScope);
connectQos.setSessionName(destinationSessionName);
connectQos.setUserId(destinationSessionName.getLoginName());
ConnectQosServer connectQosServer = new ConnectQosServer(serverScope, connectQos.getData());
connectQosServer.bypassCredentialCheck(true);
long sessionTimeout = serverScope.getProperty().get("session.ptp.defaultTimeout", -1L);
connectQosServer.getSessionQos().setSessionTimeout(sessionTimeout); // Or use message timeout?
for (int i=0; ; i++) {
if (i>=20) {
String tmp = "Sending PtP message '" + cacheEntry.getLogId() + "' to '" + destination.getDestination() + "' failed, the message is rejected.";
String status = "destinationIsSession='" + destinationIsSession + "'" +
" forceQueing='" + forceQueing + "' wantsPtP='" + wantsPtP +"'";
throw new XmlBlasterException(serverScope, ErrorCode.INTERNAL_NOTIMPLEMENTED, ME, tmp +
"the combination '" + status + "' is not handled");
}
if (i>0) { try { Thread.sleep(1L); } catch( InterruptedException ie) {}}
/*ConnectReturnQosServer q = */authenticate.connect(connectQosServer);
receiverSessionInfo = authenticate.getSessionInfo(destination.getDestination());
if (receiverSessionInfo == null) continue;
receiverSessionInfo.getLock().lock();
if (!receiverSessionInfo.isAlive()) {
receiverSessionInfo.releaseLockAssertOne("Topic=" + getId());
receiverSessionInfo = null;
continue;
}
break;
}
}
if (log.isLoggable(Level.FINE)) log.fine(ME+": Queuing PtP message '" + cacheEntry.getLogId() + "' for destination [" + destination.getDestination() + "]");
MsgQueueUpdateEntry msgEntry = new MsgQueueUpdateEntry(serverScope,
cacheEntry,
receiverSessionInfo.getSessionQueue().getStorageId(),
destination.getDestination(),
Constants.SUBSCRIPTIONID_PtP, false);
receiverSessionInfo.queueMessage(msgEntry);
continue;
}
finally {