1
2
3
4
5
6
7
8
9
10
11 package psiprobe.beans;
12
13 import jakarta.inject.Inject;
14
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.concurrent.locks.ReentrantLock;
20
21 import javax.naming.NamingException;
22
23 import org.apache.catalina.Context;
24 import org.apache.catalina.Wrapper;
25 import org.apache.catalina.util.ServerInfo;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.springframework.beans.factory.annotation.Value;
29
30 import psiprobe.TomcatContainer;
31 import psiprobe.model.ApplicationResource;
32
33
34
35
36
37
38
39 public class ContainerWrapperBean {
40
41
42 private static final Logger logger = LoggerFactory.getLogger(ContainerWrapperBean.class);
43
44
45 private volatile TomcatContainer tomcatContainer;
46
47
48 private final ReentrantLock lock = new ReentrantLock();
49
50
51 @Inject
52 private List<String> adapterClasses;
53
54
55 private ResourceResolver resourceResolver;
56
57
58 private boolean forceFirstAdapter;
59
60
61 @Inject
62 private Map<String, ResourceResolver> resourceResolvers;
63
64
65
66
67
68
69 public boolean isForceFirstAdapter() {
70 return forceFirstAdapter;
71 }
72
73
74
75
76
77
78
79
80
81 @Value("false")
82 public void setForceFirstAdapter(boolean forceFirstAdapter) {
83 this.forceFirstAdapter = forceFirstAdapter;
84 }
85
86
87
88
89
90
91 public void setWrapper(Wrapper wrapper) {
92 if (tomcatContainer == null) {
93
94 lock.lock();
95 try {
96 if (tomcatContainer == null) {
97
98 String serverInfo = ServerInfo.getServerInfo();
99 logger.info("Server info: {}", serverInfo);
100 for (String className : adapterClasses) {
101 try {
102 Object obj = Class.forName(className).getDeclaredConstructor().newInstance();
103 logger.debug("Testing container adapter: {}", className);
104 if (obj instanceof TomcatContainer container) {
105 if (forceFirstAdapter || container.canBoundTo(serverInfo)) {
106 logger.info("Using {}", className);
107 tomcatContainer = (TomcatContainer) obj;
108 tomcatContainer.setWrapper(wrapper);
109 break;
110 }
111 logger.debug("Cannot bind {} to {}", className, serverInfo);
112 } else {
113 logger.error("{} does not implement {}", className,
114 TomcatContainer.class.getName());
115 }
116 } catch (Exception e) {
117 logger.debug("", e);
118 logger.info("Failed to load {}", className);
119 }
120 }
121
122 if (tomcatContainer == null) {
123 logger.error("No suitable container adapter found!");
124 }
125 }
126 } finally {
127 lock.unlock();
128 }
129 }
130
131 try {
132 if (tomcatContainer != null && wrapper == null) {
133 logger.info("Unregistering container adapter");
134 tomcatContainer.setWrapper(null);
135 }
136 } catch (Exception e) {
137 logger.error("Could not unregister container adapter", e);
138 }
139 }
140
141
142
143
144
145
146 public TomcatContainer getTomcatContainer() {
147 return tomcatContainer;
148 }
149
150
151
152
153
154
155 public ResourceResolver getResourceResolver() {
156 if (resourceResolver == null) {
157 if (System.getProperty("jboss.server.name") != null) {
158 resourceResolver = resourceResolvers.get("jboss");
159 logger.info("Using JBOSS resource resolver");
160 } else {
161 resourceResolver = resourceResolvers.get("default");
162 logger.info("Using DEFAULT resource resolver");
163 }
164 }
165 return resourceResolver;
166 }
167
168
169
170
171
172
173
174
175 public List<ApplicationResource> getDataSources() throws NamingException {
176 List<ApplicationResource> resources = new ArrayList<>(getPrivateDataSources());
177 resources.addAll(getGlobalDataSources());
178 return resources;
179 }
180
181
182
183
184
185
186
187
188 public List<ApplicationResource> getPrivateDataSources() throws NamingException {
189 List<ApplicationResource> resources = new ArrayList<>();
190 if (tomcatContainer != null && getResourceResolver().supportsPrivateResources()) {
191 for (Context app : getTomcatContainer().findContexts()) {
192 List<ApplicationResource> appResources =
193 getResourceResolver().getApplicationResources(app, this);
194
195 filterDataSources(appResources, resources);
196 }
197 }
198 return resources;
199 }
200
201
202
203
204
205
206
207
208 public List<ApplicationResource> getGlobalDataSources() throws NamingException {
209 List<ApplicationResource> resources = new ArrayList<>();
210 if (getResourceResolver().supportsGlobalResources()) {
211 List<ApplicationResource> globalResources = getResourceResolver().getApplicationResources();
212
213 filterDataSources(globalResources, resources);
214 }
215 return resources;
216 }
217
218
219
220
221
222
223
224 protected void filterDataSources(Iterable<ApplicationResource> resources,
225 Collection<ApplicationResource> dataSources) {
226
227 for (ApplicationResource res : resources) {
228 if (res.getDataSourceInfo() != null) {
229 dataSources.add(res);
230 }
231 }
232 }
233
234 }