001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.monitoring.jta;
018    
019    import javax.annotation.Resource;
020    import javax.interceptor.AroundInvoke;
021    import javax.interceptor.AroundTimeout;
022    import javax.interceptor.Interceptor;
023    import javax.interceptor.InvocationContext;
024    import javax.transaction.Status;
025    import javax.transaction.Synchronization;
026    import javax.transaction.TransactionSynchronizationRegistry;
027    
028    @Interceptor
029    @JTAMonitored
030    public class JTAInterceptor {
031        private static final String RESOURCE_KEY = JTAInterceptor.class.getName();
032    
033        @Resource
034        private TransactionSynchronizationRegistry transactionSynchronizationRegistry;
035    
036        @AroundInvoke
037        @AroundTimeout
038        public Object jta(final InvocationContext invocationContext) throws Throwable {
039            if (transactionSynchronizationRegistry.getResource(RESOURCE_KEY) == null) {
040                JTAGauges.ACTIVE.incrementAndGet();
041                transactionSynchronizationRegistry.putResource(RESOURCE_KEY, Boolean.TRUE);
042                transactionSynchronizationRegistry.registerInterposedSynchronization(new JTACounterSynchronization());
043            }
044            return invocationContext.proceed();
045        }
046    
047        private static class JTACounterSynchronization implements Synchronization {
048            @Override
049            public void beforeCompletion() {
050                // no-op
051            }
052    
053            @Override
054            public void afterCompletion(final int status) {
055                if (status == Status.STATUS_COMMITTED) {
056                    JTAGauges.COMMITTED.incrementAndGet();
057                } else if (status == Status.STATUS_ROLLEDBACK) {
058                    JTAGauges.ROLLBACKED.incrementAndGet();
059                }
060                JTAGauges.ACTIVE.decrementAndGet();
061            }
062        }
063    }