+ @Override
+ public void close() throws Exception {
+
+ if (baCommitHandlerRegistration != null) {
+ baCommitHandlerRegistration.close();
+ }
+ if (biCommitHandlerRegistration != null) {
+ biCommitHandlerRegistration.close();
+ }
+
+ }
+
+ private class DomToBindingTransaction implements
+ DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+
+ private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
+ private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
+
+ public DomToBindingTransaction(
+ org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
+ DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
+ super();
+ this.backing = backing;
+ this.modification = modification;
+ bindingOpenedTransactions.put(backing.getIdentifier(), this);
+ }
+
+ @Override
+ public DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getModification() {
+ return modification;
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // backing.cancel();
+ return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ Future<RpcResult<TransactionStatus>> result = backing.commit();
+ try {
+ RpcResult<TransactionStatus> baResult = result.get();
+ return Rpcs.<Void> getRpcResult(baResult.isSuccessful(), null, baResult.getErrors());
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("", e);
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("", e);
+ }
+ }
+ }
+
+ private class BindingToDomTransaction implements
+ DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ private DataModificationTransaction backing;
+ private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+ public BindingToDomTransaction(DataModificationTransaction backing,
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+ this.backing = backing;
+ this.modification = modification;
+ domOpenedTransactions.put(backing.getIdentifier(), this);
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+ return modification;
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ Future<RpcResult<TransactionStatus>> result = backing.commit();
+ try {
+ RpcResult<TransactionStatus> biResult = result.get();
+ return Rpcs.<Void> getRpcResult(biResult.isSuccessful(), null, biResult.getErrors());
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("", e);
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("", e);
+ } finally {
+ domOpenedTransactions.remove(backing.getIdentifier());
+ }
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ domOpenedTransactions.remove(backing.getIdentifier());
+ return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ }
+ }
+
+ private class BindingToDomCommitHandler implements
+ DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ @Override
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
+
+ /**
+ * Transaction was created as DOM transaction, in that case we do
+ * not need to forward it back.
+ */
+ if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
+
+ return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+ }
+ DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
+ BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
+ LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+ domTransaction.getIdentifier());
+ return wrapped;
+ }
+ }
+
+ private class DomToBindingCommitHandler implements //
+ RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject>>, //
+ DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+
+ @Override
+ public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
+ .getPath());
+ // FIXME: do registration based on only active commit handlers.
+
+ }
+
+ @Override
+ public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+ // NOOP for now
+ // FIXME: do registration based on only active commit handlers.
+ }
+
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
+ DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
+ Object identifier = domTransaction.getIdentifier();
+
+ /**
+ * We checks if the transcation was originated in this mapper. If it
+ * was originated in this mapper we are returing allways success
+ * commit hanlder to prevent creating loop in two-phase commit and
+ * duplicating data.
+ */
+ if (domOpenedTransactions.containsKey(identifier)) {
+ return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+ }
+
+ org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
+ DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
+ LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+ baTransaction.getIdentifier());
+ return forwardedTransaction;
+ }
+ }