View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.persistence.jpa.dao;
20  
21  import java.lang.reflect.Field;
22  import java.net.InetAddress;
23  import java.util.ArrayList;
24  import java.util.LinkedHashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.stream.Collectors;
28  import org.apache.commons.lang3.tuple.Triple;
29  import org.apache.openjpa.conf.OpenJPAConfiguration;
30  import org.apache.openjpa.event.RemoteCommitEventManager;
31  import org.apache.openjpa.event.RemoteCommitProvider;
32  import org.apache.openjpa.event.TCPRemoteCommitProvider;
33  import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
34  import org.apache.openjpa.persistence.OpenJPAPersistence;
35  import org.apache.syncope.core.persistence.api.dao.PersistenceInfoDAO;
36  import org.apache.syncope.core.persistence.api.entity.Entity;
37  import org.springframework.util.ClassUtils;
38  import org.springframework.util.ReflectionUtils;
39  
40  public class JPAPersistenceInfoDAO extends AbstractDAO<Entity> implements PersistenceInfoDAO {
41  
42      @Override
43      public Map<String, Object> info() {
44          Map<String, Object> result = new LinkedHashMap<>();
45  
46          OpenJPAEntityManagerFactorySPI emfspi =
47                  (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(entityManagerFactory());
48          OpenJPAConfiguration conf = emfspi.getConfiguration();
49  
50          Map<String, Object> properties = emfspi.getProperties();
51          result.put("vendor", properties.get("VendorName"));
52          result.put("version", properties.get("VersionNumber"));
53          result.put("platform", properties.get("Platform"));
54  
55          Map<String, Object> remoteCommitProvider = new LinkedHashMap<>();
56          result.put("remoteCommitProvider", remoteCommitProvider);
57  
58          RemoteCommitEventManager rcem = conf.getRemoteCommitEventManager();
59  
60          remoteCommitProvider.put("remoteEventsEnabled", rcem.areRemoteEventsEnabled());
61          remoteCommitProvider.put("transmitPersistedObjectIds", rcem.getTransmitPersistedObjectIds());
62          remoteCommitProvider.put("failFast", rcem.isFailFast());
63  
64          RemoteCommitProvider rcp = rcem.getRemoteCommitProvider();
65          List<Triple<String, Integer, Boolean>> addresses = new ArrayList<>();
66          if (rcp instanceof TCPRemoteCommitProvider) {
67              try {
68                  Field addressesField = ReflectionUtils.findField(TCPRemoteCommitProvider.class, "_addresses");
69                  addressesField.setAccessible(true);
70  
71                  Class<?> hostClass = ClassUtils.forName(
72                          "org.apache.openjpa.event.TCPRemoteCommitProvider$HostAddress",
73                          ClassUtils.getDefaultClassLoader());
74                  Field addressField = ReflectionUtils.findField(hostClass, "_address");
75                  addressField.setAccessible(true);
76                  Field portField = ReflectionUtils.findField(hostClass, "_port");
77                  portField.setAccessible(true);
78                  Field isAvailableField = ReflectionUtils.findField(hostClass, "_isAvailable");
79                  isAvailableField.setAccessible(true);
80  
81                  @SuppressWarnings("unchecked")
82                  List<Object> hosts = (List<Object>) ReflectionUtils.getField(addressesField, rcp);
83                  hosts.forEach(host -> {
84                      InetAddress address = (InetAddress) ReflectionUtils.getField(addressField, host);
85                      Integer port = (Integer) ReflectionUtils.getField(portField, host);
86                      Boolean isAvailable = (Boolean) ReflectionUtils.getField(isAvailableField, host);
87  
88                      addresses.add(Triple.of(address.getHostAddress(), port, isAvailable));
89                  });
90              } catch (Exception e) {
91                  LOG.error("Could not fetch information about TCPRemoteCommitProvider", e);
92              }
93          }
94  
95          remoteCommitProvider.put(
96                  "addresses",
97                  addresses.stream().map(address -> {
98                      Map<String, Object> map = new LinkedHashMap<>();
99                      map.put("ip", address.getLeft());
100                     map.put("port", address.getMiddle());
101                     map.put("available", address.getRight());
102                     return map;
103                 }).collect(Collectors.toList()));
104 
105         return result;
106     }
107 }