package won.node.facet.impl; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.StmtIterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import won.protocol.exception.*; import won.protocol.message.WonMessage; import won.protocol.model.Connection; import won.protocol.model.FacetType; import won.protocol.repository.ConnectionRepository; import won.protocol.vocabulary.WON; /** * Created with IntelliJ IDEA. * User: Danijel * Date: 9.12.13. * Time: 19.19 * To change this template use File | Settings | File Templates. */ public class ParticipantFacetImpl extends AbstractFacet { private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private ConnectionRepository connectionRepository; @Override public FacetType getFacetType() { return FacetType.ParticipantFacet; } public void connectFromNeed(final Connection con, final Model content, final WonMessage wonMessage) throws NoSuchNeedException, IllegalMessageForNeedStateException, ConnectionAlreadyExistsException { final Connection connectionForRunnable = con; logger.debug("Participant: ConnectFromNeed"); executorService.execute(new Runnable() { @Override public void run() { //TODO: use new system // ownerProtocolOwnerService.connect( // con.getNeedURI(), con.getRemoteNeedURI(), // connectionForRunnable.getConnectionURI(), content, wonMessage); } }); } @Override public void openFromOwner(final Connection con, final Model content, final WonMessage wonMessage) throws NoSuchConnectionException, IllegalMessageForConnectionStateException { //inform the other side logger.debug("Participant: OpenFromOwner"); if (con.getRemoteConnectionURI() != null) { executorService.execute(new Runnable() { @Override public void run() { try { //TODO: use new system // needFacingConnectionClient.open(con, content, wonMessage); } catch (Exception e) { logger.debug("caught Exception", e); } } }); } } @Override public void closeFromOwner(final Connection con, final Model content, final WonMessage wonMessage) throws NoSuchConnectionException, IllegalMessageForConnectionStateException { //inform the other side logger.debug("Participant: CloseFromOwner"); if (con.getRemoteConnectionURI() != null) { executorService.execute(new Runnable() { @Override public void run() { try { //TODO: use new system // needFacingConnectionClient.close(con, content, wonMessage); } catch (Exception e) { logger.debug("caught Exception", e); } } }); } } public void closeFromNeed(final Connection con, final Model content, final WonMessage wonMessage) throws NoSuchConnectionException, IllegalMessageForConnectionStateException { //inform the need side logger.debug("Participant: CloseFromNeed"); //TODO: create utilities for accessing addtional content Resource res = content.getResource(content.getNsPrefixURI("")); Resource message = null; if (res == null) { logger.debug("no default prexif specified in model, could not obtain additional content, using ABORTED message"); message = WON_TX.COORDINATION_MESSAGE_ABORT; } //TODO: make sure there is only one message in the content message = res.getPropertyResourceValue(WON_TX.COORDINATION_MESSAGE); final Resource msgForRunnable = message; executorService.execute(new Runnable() { @Override public void run() { try { //if (msgForRunnable == WON_TX.COORDINATION_MESSAGE_ABORT){ if(msgForRunnable!=null){ if (msgForRunnable.equals(WON_TX.COORDINATION_MESSAGE_ABORT)){ logger.debug("Abort the following connection: "+con.getConnectionURI()+" "+con.getNeedURI()+" "+con.getRemoteNeedURI() +" "+con.getState()+ " "+con.getTypeURI()); } else { logger.debug("Committed: "+con.getConnectionURI()+" "+con.getNeedURI()+" "+con.getRemoteNeedURI() +" "+con.getState()+ " "+con.getTypeURI()); } //TODO: use new system // ownerFacingConnectionClient.close(con.getConnectionURI(), content, wonMessage); } } catch (Exception e) { logger.warn("caught WonProtocolException:", e); } } }); } public void compensate(Connection con , Model content){ //todo //TODO: create utilities for accessing addtional content /* Resource res = content.getResource(content.getNsPrefixURI("")); if (res == null) { logger.debug("no default prexif specified in model, could not obtain additional content, using ABORTED message"); } res.removeAll(WON_TX.COORDINATION_MESSAGE); res.addProperty(WON_TX.COORDINATION_MESSAGE, WON_TX.COORDINATION_MESSAGE_ABORT_AND_COMPENSATE);*/ logger.debug("Compensated: "+con.getConnectionURI()+" "+con.getNeedURI()+" "+con.getRemoteNeedURI() +" "+con.getState()+ " "+con.getTypeURI()); } @Override public void connectFromOwner(final Connection con, final Model content, final WonMessage wonMessage) throws NoSuchNeedException, IllegalMessageForNeedStateException, ConnectionAlreadyExistsException { logger.debug("Participant: ConntectFromOwner"); Resource baseRes = content.getResource(content.getNsPrefixURI("")); StmtIterator stmtIterator = baseRes.listProperties(WON.HAS_REMOTE_FACET); if (!stmtIterator.hasNext()) throw new IllegalArgumentException("at least one RDF node must be of type won:hasRemoteFacet"); //TODO: This should just remove RemoteFacet from content and replace the value of Facet with the one from RemoteFacet final Model remoteFacetModel = ModelFactory.createDefaultModel(); remoteFacetModel.setNsPrefix("", "no:uri"); baseRes = remoteFacetModel.createResource(remoteFacetModel.getNsPrefixURI("")); Resource remoteFacetResource = stmtIterator.next().getObject().asResource(); baseRes.addProperty(WON.HAS_FACET, remoteFacetModel.createResource(remoteFacetResource.getURI())); final Connection connectionForRunnable = con; //send to need executorService.execute(new Runnable() { @Override public void run() { try { //TODO: use new system // Future<URI> remoteConnectionURI = needProtocolNeedService.connect( // con.getRemoteNeedURI(),con.getNeedURI(), // connectionForRunnable.getConnectionURI(), remoteFacetModel, wonMessage); //dataService.updateRemoteConnectionURI(con, remoteConnectionURI.get()); } catch (Exception e) { // we can't connect the connection. we send a close back to the owner // TODO should we introduce a new protocol method connectionFailed (because it's not an owner deny but some protocol-level error)? // For now, we call the close method as if it had been called from the remote side // TODO: even with this workaround, it would be good to send a content along with the close (so we can explain what happened). // try { // needFacingConnectionCommunicationService.close( // connectionForRunnable.getConnectionURI(), content, wonMessage); // } catch (NoSuchConnectionException e1) { // logger.warn("caught NoSuchConnectionException:", e1); // } catch (IllegalMessageForConnectionStateException e1) { // logger.warn("caught IllegalMessageForConnectionStateException:", e1); // } } } }); } }