Esempio n. 1
0
  /**
   * Starts a new transaction on the database. Note, that transaction can also be nested. So in
   * order to work properly ALWAYS acquire a {@link DatabaseAdapter} instance via the {@link
   * DatabaseAdapter#getInstance(Context)} method.
   *
   * @return Current {@link DatabaseAdapter} instance.
   */
  public DatabaseAdapter beginTransaction() {
    open();

    mDb.beginTransactionWithListener(TransactionListener.getFor(this));

    return this;
  }
Esempio n. 2
0
 private void transition(SplitTransactionPhase nextPhase, boolean isRollback) throws IOException {
   if (!isRollback) {
     // Add to the journal first, because if the listener throws an exception
     // we need to roll back starting at 'nextPhase'
     this.journal.add(new JournalEntryImpl(nextPhase));
   }
   for (int i = 0; i < listeners.size(); i++) {
     TransactionListener listener = listeners.get(i);
     if (!isRollback) {
       listener.transition(this, currentPhase, nextPhase);
     } else {
       listener.rollback(this, currentPhase, nextPhase);
     }
   }
   currentPhase = nextPhase;
 }
 @Override
 public void registerTransactionListener(final TransactionListener listener)
     throws BCSAPIException {
   try {
     addTopicListener(
         "transaction",
         listener,
         bytes -> {
           APITransaction transaction = null;
           try {
             transaction = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(bytes));
           } catch (Exception e) {
             log.error("Transaction message error", e);
           }
           return transaction;
         },
         transaction -> {
           if (transaction != null)
             try {
               listener.process(transaction);
             } catch (HyperLedgerException e) {
               log.error("Error in transaction processing", e);
             }
         });
   } catch (ConnectorException e) {
     throw new BCSAPIException(e);
   }
 }
  @Override
  public void fromApp(final SipResponse res, final TransactionListener listener) {

    Preconditions.checkNotNull(res);

    if ((res.getStatus().getCode() / 100) == 1) {
      switch (this.state) {
        case Trying:
          this.response = res;
          this.setState(State.Proceeding);
          listener.sendToNetwork(this.flowId, this.response);
          break;
        case Proceeding:
          this.response = res;
          listener.sendToNetwork(this.flowId, this.response);
          break;
        case Initial:
        case Completed:
        case Terminated:
          break;
      }
    } else if ((res.getStatus().getCode() / 100) >= 2) {

      // schedule the expiry timer.
      // TODO change to dynamic value.
      listener.schedule(this.getBranchId(), Duration.ofSeconds(32));

      switch (this.state) {
        case Trying:
          this.response = res;
          this.setState(State.Completed);
          listener.sendToNetwork(this.flowId, this.response);
          break;
        case Proceeding:
          this.response = res;
          this.setState(State.Completed);
          listener.sendToNetwork(this.flowId, this.response);
          break;
        case Initial:
        case Completed:
        case Terminated:
          break;
      }
    }
  }
  /**
   * Notify all listeners that a rollback is about to occur. If a listener throws an exception then
   * no further listeners will be notified and a StandardException with shutdown database(?)
   * severity will be thrown.
   *
   * @throws StandardException
   */
  public void preRollbackNotify() throws StandardException {
    if (listeners.isEmpty()) return;

    for (Iterator i = listeners.iterator(); i.hasNext(); ) {
      TransactionListener listener = (TransactionListener) i.next();

      try {
        listener.preRollback();
        i.remove();
      } catch (StandardException se) {
        // TODO: Define behaviour on exception during rollback.

        if (se.getSeverity() < ExceptionSeverity.TRANSACTION_SEVERITY) {}

        throw se;
      }
    }
  }
  /**
   * Notify all listeners that a commit is about to occur. If a listener throws an exception then no
   * further listeners will be notified and a StandardException with rollback severity will be
   * thrown.
   *
   * @throws StandardException
   */
  public void preCommitNotify() throws StandardException {
    if (listeners.isEmpty()) return;

    for (Iterator i = listeners.iterator(); i.hasNext(); ) {
      TransactionListener listener = (TransactionListener) i.next();

      try {
        if (listener.preCommit()) i.remove();
      } catch (StandardException se) {
        // This catches any exceptions that have Transaction severity
        // or less (e.g. Statement exception).
        // If we received any lesser
        // error then we abort the transaction anyway.

        if (se.getSeverity() < ExceptionSeverity.TRANSACTION_SEVERITY) {
          throw StandardException.newException(SQLState.XACT_COMMIT_EXCEPTION, se);
        }

        throw se;
      }
    }
  }
  @Override
  public void fromNetwork(final SipRequestReceivedEvent e, final TransactionListener listener) {

    switch (this.state) {
      case Initial:
        // pass the message on to the app layer.
        this.flowId = e.getFlowId();
        this.setState(State.Trying);
        listener.sendToApp(null, e.getMessage());
        break;
      case Trying:
        break;
      case Proceeding:
      case Completed:
        // always send the response down the same flow as we received it.
        Preconditions.checkNotNull(this.response);
        listener.sendToNetwork(e.getFlowId(), this.response);
        break;
      case Terminated:
        break;
    }
  }
  @Override
  public void spendingTransactions(List<TID> tids, final TransactionListener listener)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer scanAccountProducer =
          session.createProducer(session.createQueue("spendingTransactions"));
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      for (TID tid : tids) {
        builder.addHash(ByteString.copyFrom(tid.unsafeGetArray()));
      }
      m.setPayload(builder.build().toByteArray());

      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for spendingt ransactions request", e);
            }
          });

      scanAccountProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }
  private void scanRequest(
      Collection<Script> match, final TransactionListener listener, String requestQueue)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer exactMatchProducer =
          session.createProducer(session.createQueue(requestQueue));
      BCSAPIMessage.ExactMatchRequest.Builder builder =
          BCSAPIMessage.ExactMatchRequest.newBuilder();
      for (Script d : match) {
        builder.addMatch(ByteString.copyFrom(d.toByteArray()));
      }
      m.setPayload(builder.build().toByteArray());
      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for scan matching transactions", e);
            }
          });

      exactMatchProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }
Esempio n. 10
0
  private void scanRequest(
      MasterPublicKey master, int lookAhead, final TransactionListener listener, String request)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer scanAccountProducer = session.createProducer(session.createQueue(request));
      BCSAPIMessage.AccountRequest.Builder builder = BCSAPIMessage.AccountRequest.newBuilder();
      builder.setPublicKey(master.serialize(true));
      builder.setLookAhead(lookAhead);
      m.setPayload(builder.build().toByteArray());

      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for account scan transactions", e);
            }
          });

      scanAccountProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }