You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by su...@apache.org on 2022/12/23 16:09:19 UTC

[shardingsphere] branch master updated: Refactor NarayanaXATransactionManagerProvider (#23070)

This is an automated email from the ASF dual-hosted git repository.

sunnianjun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new db2fe4062d1 Refactor NarayanaXATransactionManagerProvider (#23070)
db2fe4062d1 is described below

commit db2fe4062d1289f5910ee03d8205b088706a21ca
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sat Dec 24 00:09:04 2022 +0800

    Refactor NarayanaXATransactionManagerProvider (#23070)
    
    * Refactor NarayanaXATransactionManagerProvider
    
    * Refactor NarayanaXATransactionManagerProvider
---
 .../infra/util/util/ReflectionUtil.java            | 72 ++++++++++++++++++++++
 .../infra/util/util/ReflectionUtilTest.java        | 39 ++++++++++++
 .../infra/util/util/fixture/ReflectionFixture.java | 33 ++++++++++
 .../NarayanaXATransactionManagerProvider.java      | 52 ++++++----------
 4 files changed, 163 insertions(+), 33 deletions(-)

diff --git a/infra/util/src/main/java/org/apache/shardingsphere/infra/util/util/ReflectionUtil.java b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/util/ReflectionUtil.java
new file mode 100644
index 00000000000..0d260cdcd0a
--- /dev/null
+++ b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/util/ReflectionUtil.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.util.util;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.SneakyThrows;
+
+import java.lang.reflect.Field;
+
+/**
+ * Reflection utility.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ReflectionUtil {
+    
+    /**
+     * Get field value.
+     *
+     * @param target target
+     * @param fieldName field name
+     * @return field value
+     */
+    @SneakyThrows(ReflectiveOperationException.class)
+    public static Object getStaticFieldValue(final Class<?> target, final String fieldName) {
+        Field field = target.getDeclaredField(fieldName);
+        boolean accessible = field.isAccessible();
+        if (!accessible) {
+            field.setAccessible(true);
+        }
+        Object result = field.get(target);
+        if (!accessible) {
+            field.setAccessible(false);
+        }
+        return result;
+    }
+    
+    /**
+     * Set field value.
+     * 
+     * @param target target
+     * @param fieldName field name
+     * @param value value
+     */
+    @SneakyThrows(ReflectiveOperationException.class)
+    public static void setStaticFieldValue(final Class<?> target, final String fieldName, final Object value) {
+        Field field = target.getDeclaredField(fieldName);
+        boolean accessible = field.isAccessible();
+        if (!accessible) {
+            field.setAccessible(true);
+        }
+        field.set(target, value);
+        if (!accessible) {
+            field.setAccessible(false);
+        }
+    }
+}
diff --git a/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/ReflectionUtilTest.java b/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/ReflectionUtilTest.java
new file mode 100644
index 00000000000..ce747069490
--- /dev/null
+++ b/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/ReflectionUtilTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.util.util;
+
+import org.apache.shardingsphere.infra.util.util.fixture.ReflectionFixture;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public final class ReflectionUtilTest {
+    
+    @Test
+    public void assertGetStaticFieldValue() {
+        assertThat(ReflectionUtil.getStaticFieldValue(ReflectionFixture.class, "staticValue"), is("foo"));
+    }
+    
+    @Test
+    public void assertSetStaticFieldValue() {
+        ReflectionUtil.setStaticFieldValue(ReflectionFixture.class, "staticValue", "bar");
+        assertThat(ReflectionFixture.getStaticValue(), is("bar"));
+        ReflectionUtil.setStaticFieldValue(ReflectionFixture.class, "staticValue", "foo");
+    }
+}
diff --git a/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/fixture/ReflectionFixture.java b/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/fixture/ReflectionFixture.java
new file mode 100644
index 00000000000..e71d8660c20
--- /dev/null
+++ b/infra/util/src/test/java/org/apache/shardingsphere/infra/util/util/fixture/ReflectionFixture.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.util.util.fixture;
+
+public final class ReflectionFixture {
+    
+    @SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
+    private static String staticValue = "foo";
+    
+    /**
+     * Get static value.
+     * 
+     * @return static value
+     */
+    public static String getStaticValue() {
+        return staticValue;
+    }
+}
diff --git a/kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java b/kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java
index 454b2ea5293..22a90706577 100644
--- a/kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java
+++ b/kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java
@@ -27,6 +27,7 @@ import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
 import com.arjuna.common.util.propertyservice.PropertiesFactory;
 import lombok.Getter;
 import lombok.SneakyThrows;
+import org.apache.shardingsphere.infra.util.util.ReflectionUtil;
 import org.apache.shardingsphere.transaction.xa.spi.SingleXAResource;
 import org.apache.shardingsphere.transaction.xa.spi.XATransactionManagerProvider;
 
@@ -34,7 +35,6 @@ import javax.sql.XADataSource;
 import javax.transaction.RollbackException;
 import javax.transaction.SystemException;
 import javax.transaction.TransactionManager;
-import java.lang.reflect.Field;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentMap;
 
@@ -84,48 +84,34 @@ public final class NarayanaXATransactionManagerProvider implements XATransaction
     public void close() throws Exception {
         recoveryManagerService.stop();
         recoveryManagerService.destroy();
-        propertiesFactoryClean();
-        beanPopulatorClean();
-        atomicActionRecoveryClean();
-        xaRecoveryModuleClean();
-        storeManagerClean();
+        cleanPropertiesFactory();
+        cleanBeanInstances();
+        cleanAtomicActionRecovery();
+        cleanXARecoveryModule();
+        cleanStoreManager();
     }
     
-    private void propertiesFactoryClean() throws NoSuchFieldException, IllegalAccessException {
-        Field field = PropertiesFactory.class.getDeclaredField("delegatePropertiesFactory");
-        field.setAccessible(true);
-        field.set("delegatePropertiesFactory", null);
+    private void cleanPropertiesFactory() {
+        ReflectionUtil.setStaticFieldValue(PropertiesFactory.class, "delegatePropertiesFactory", null);
     }
     
-    private void beanPopulatorClean() throws NoSuchFieldException, IllegalAccessException {
-        Field field = BeanPopulator.class.getDeclaredField("beanInstances");
-        field.setAccessible(true);
-        ConcurrentMap map = (ConcurrentMap) field.get("beanInstances");
-        map.clear();
+    @SuppressWarnings("unchecked")
+    private void cleanBeanInstances() {
+        ((ConcurrentMap<String, Object>) ReflectionUtil.getStaticFieldValue(BeanPopulator.class, "beanInstances")).clear();
     }
     
-    private void atomicActionRecoveryClean() throws NoSuchFieldException, IllegalAccessException {
-        Field field = AtomicActionRecoveryModule.class.getDeclaredField("_recoveryStore");
-        field.setAccessible(true);
-        field.set("_recoveryStore", null);
+    private void cleanAtomicActionRecovery() {
+        ReflectionUtil.setStaticFieldValue(AtomicActionRecoveryModule.class, "_recoveryStore", null);
     }
     
-    private void xaRecoveryModuleClean() throws NoSuchFieldException, IllegalAccessException {
-        Field field = XARecoveryModule.class.getDeclaredField("registeredXARecoveryModule");
-        field.setAccessible(true);
-        field.set("registeredXARecoveryModule", null);
+    private void cleanXARecoveryModule() {
+        ReflectionUtil.setStaticFieldValue(XARecoveryModule.class, "registeredXARecoveryModule", null);
     }
     
-    private void storeManagerClean() throws NoSuchFieldException, IllegalAccessException {
-        Field actionStoreField = StoreManager.class.getDeclaredField("actionStore");
-        actionStoreField.setAccessible(true);
-        actionStoreField.set("actionStore", null);
-        Field stateStoreField = StoreManager.class.getDeclaredField("stateStore");
-        stateStoreField.setAccessible(true);
-        stateStoreField.set("stateStore", null);
-        Field communicationStoreField = StoreManager.class.getDeclaredField("communicationStore");
-        communicationStoreField.setAccessible(true);
-        communicationStoreField.set("communicationStore", null);
+    private void cleanStoreManager() {
+        ReflectionUtil.setStaticFieldValue(StoreManager.class, "actionStore", null);
+        ReflectionUtil.setStaticFieldValue(StoreManager.class, "stateStore", null);
+        ReflectionUtil.setStaticFieldValue(StoreManager.class, "communicationStore", null);
     }
     
     @Override