package xdi2.messaging.container.interceptor.impl.push; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xdi2.agent.XDIAgent; import xdi2.agent.impl.XDIBasicAgent; import xdi2.client.XDIClient; import xdi2.client.XDIClientRoute; import xdi2.client.exceptions.Xdi2AgentException; import xdi2.client.exceptions.Xdi2ClientException; import xdi2.client.impl.XDIAbstractClient; import xdi2.client.manipulator.Manipulator; import xdi2.core.Graph; import xdi2.core.features.linkcontracts.instance.RelationshipLinkContract; import xdi2.core.syntax.XDIAddress; import xdi2.core.syntax.XDIArc; import xdi2.core.syntax.XDIStatement; import xdi2.messaging.Message; import xdi2.messaging.MessageEnvelope; import xdi2.messaging.container.MessagingContainer; import xdi2.messaging.operations.Operation; import xdi2.messaging.response.MessagingResponse; public class BasicPushGateway implements PushGateway { private static final Logger log = LoggerFactory.getLogger(BasicPushGateway.class); private XDIAgent xdiAgent; private Collection<Manipulator> manipulators; public BasicPushGateway(XDIAgent xdiAgent, Collection<Manipulator> manipulators) { this.xdiAgent = xdiAgent; this.manipulators = manipulators; } public BasicPushGateway() { this(new XDIBasicAgent(), null); } @Override public void executePush(MessagingContainer messagingContainer, RelationshipLinkContract pushLinkContract, Set<Operation> pushedOperations, Map<Operation, Graph> pushedOperationResultGraphs, Map<Operation, XDIAddress> pushedXDIAddressMap, Map<Operation, List<XDIStatement>> pushedXDIStatementMap) throws Xdi2AgentException, Xdi2ClientException { List<Exception> exs = new ArrayList<Exception> (); for (XDIArc toPeerRootXDIArc : pushLinkContract.getPushToPeerRootXDIArcs()) { if (log.isDebugEnabled()) log.debug("Trying to push to " + toPeerRootXDIArc); try { // find route to this target XDIClientRoute<?> xdiClientRoute; try { xdiClientRoute = this.getXdiAgent().route(toPeerRootXDIArc); if (xdiClientRoute == null) { log.warn("No route for " + toPeerRootXDIArc + ". Skipping push command."); continue; } } catch (Xdi2AgentException ex) { log.error("Agent problem while routing to target " + toPeerRootXDIArc + ": " + ex.getMessage() + ". Skipping", ex); exs.add(ex); continue; } catch (Xdi2ClientException ex) { log.error("Client problem while routing to target " + toPeerRootXDIArc + ": " + ex.getMessage() + ". Skipping.", ex); exs.add(ex); continue; } // client construction step XDIClient<?> xdiClient = xdiClientRoute.constructXDIClient(); // add manipulators if supported if (xdiClient instanceof XDIAbstractClient && this.getManipulators() != null) { ((XDIAbstractClient<? extends MessagingResponse>) xdiClient).getManipulators().addManipulators(this.getManipulators()); } // message envelope construction step MessageEnvelope pushMessageEnvelope = xdiClientRoute.createMessageEnvelope(); for (Operation pushedOperation : pushedOperations) { Message pushMessage = xdiClientRoute.createMessage(pushMessageEnvelope, pushLinkContract.getAuthorizingAuthority()); pushMessage.setFromPeerRootXDIArc(messagingContainer.getOwnerPeerRootXDIArc()); pushMessage.setToPeerRootXDIArc(toPeerRootXDIArc); pushMessage.setLinkContract(pushLinkContract); pushMessage.setCorrelationXDIAddress(pushedOperation.getMessage().getContextNode().getXDIAddress()); // the $push message contains the inner pushed operation pushMessage.createPushOperation(pushedOperation.getMessage()); // and the result graph of that pushed operation Graph pushedOperationResultGraph = pushedOperationResultGraphs.get(pushedOperation); pushMessage.createOperationResult(pushedOperation.getOperationXDIAddress(), pushedOperationResultGraph); } /* Message requestMessage = xdiClientRoute.createMessage(messageEnvelope, pushLinkContract.getAuthorizingAuthority()); requestMessage.setFromPeerRootXDIArc(messagingContainer.getOwnerPeerRootXDIArc()); requestMessage.setToPeerRootXDIArc(toPeerRootXDIArc); requestMessage.setLinkContract(pushLinkContract); for (Operation pushOperation : pushLinkContractOperations) { XDIAddress pushXDIAddress = pushLinkContractXDIAddressMap == null ? null : pushLinkContractXDIAddressMap.get(pushOperation); List<XDIStatement> pushXDIStatements = pushLinkContractXDIStatementMap == null ? null : pushLinkContractXDIStatementMap.get(pushOperation); if (pushXDIAddress != null) requestMessage.createOperation(pushOperation.getOperationXDIAddress(), pushXDIAddress); if (pushXDIStatements != null) requestMessage.createOperation(pushOperation.getOperationXDIAddress(), pushXDIStatements.iterator()); } Message responseMessage = xdiClientRoute.createMessage(messageEnvelope, pushLinkContract.getAuthorizingAuthority()); responseMessage.setFromPeerRootXDIArc(messagingContainer.getOwnerPeerRootXDIArc()); responseMessage.setToPeerRootXDIArc(toPeerRootXDIArc); responseMessage.setLinkContract(pushLinkContract); responseMessage.setCorrelationXDIAddress(requestMessage.getContextNode().getXDIAddress()); for (Operation pushOperation : pushLinkContractOperations) { Graph pushLinkContractOperationResultGraph = pushLinkContractOperationResultGraphs.get(pushOperation); if (pushLinkContractOperationResultGraph != null) responseMessage.createOperation(pushOperation.getOperationXDIAddress(), new MappingXDIStatementIterator(pushLinkContractOperationResultGraph.getAllStatements())); }*/ // send the message envelope xdiClient.send(pushMessageEnvelope); // close the client // TODO: when do we close the client? if (xdiClient == null) xdiClient.close(); // done if (log.isDebugEnabled()) log.debug("Successfully pushed to " + toPeerRootXDIArc); } catch (Exception ex) { log.warn("Failed to push to " + toPeerRootXDIArc + ": " + ex.getMessage() + ". Skipping.", ex); exs.add(ex); } } // raise exception if any if (exs.size() > 0) { if (exs.size() == 1) throw new Xdi2ClientException("Push " + pushedOperations + " failed: " + exs.get(0).getMessage(), exs.get(0)); throw new Xdi2ClientException("Multiple pushes " + pushedOperations + " failed. First failed push is: " + exs.get(0), exs.get(0)); } } /* * Getters and setters */ public XDIAgent getXdiAgent() { return this.xdiAgent; } public void setXdiAgent(XDIAgent xdiAgent) { this.xdiAgent = xdiAgent; } public Collection<Manipulator> getManipulators() { return this.manipulators; } public void setManipulators(Collection<Manipulator> manipulators) { this.manipulators = manipulators; } }