1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.common.config;
18
19 import java.util.Timer;
20
21 import org.opensaml.util.resource.Resource;
22 import org.opensaml.util.resource.ResourceChangeListener;
23 import org.opensaml.util.resource.ResourceChangeWatcher;
24 import org.opensaml.util.resource.ResourceException;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import edu.internet2.middleware.shibboleth.common.service.ReloadableService;
29 import edu.internet2.middleware.shibboleth.common.service.ServiceException;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public abstract class BaseReloadableService extends BaseService implements ReloadableService {
46
47
48 private final Logger log = LoggerFactory.getLogger(BaseReloadableService.class);
49
50
51 private long resourcePollingFrequency;
52
53
54 private int resourcePollingRetryAttempts;
55
56
57 private Timer pollingTimer;
58
59
60
61
62
63
64 public BaseReloadableService() {
65 super();
66 setPollingFrequency(0);
67 setPollingRetryAttempts(0);
68 }
69
70
71
72
73
74
75 public Timer getPollingTimer(){
76 return pollingTimer;
77 }
78
79
80
81
82
83
84 public void setPollingTimer(Timer timer){
85 pollingTimer = timer;
86 }
87
88
89
90
91
92
93 public long getPollingFrequency() {
94 return resourcePollingFrequency;
95 }
96
97
98
99
100
101
102 public void setPollingFrequency(long frequency){
103 resourcePollingFrequency = frequency;
104 }
105
106
107
108
109
110
111 public int getPollingRetryAttempts() {
112 return resourcePollingRetryAttempts;
113 }
114
115
116
117
118
119
120 public void setPollingRetryAttempts(int attempts) {
121 resourcePollingRetryAttempts = attempts;
122 }
123
124
125 public void initialize() throws ServiceException {
126 if (isDestroyed()) {
127 throw new SecurityException(getId() + " service has been destroyed, it may not be initialized.");
128 }
129
130 if (isInitialized()) {
131 return;
132 }
133
134 try {
135 log.debug("Initializing {} service with resources: {}", getId(), getServiceConfigurations());
136 if (resourcePollingFrequency > 0) {
137 ResourceChangeWatcher changeWatcher;
138 ResourceChangeListener changeListener = new ConfigurationResourceListener();
139 for (Resource configurationResournce : getServiceConfigurations()) {
140 changeWatcher = new ResourceChangeWatcher(configurationResournce, resourcePollingFrequency,
141 resourcePollingRetryAttempts);
142 changeWatcher.getResourceListeners().add(changeListener);
143 pollingTimer.schedule(changeWatcher, resourcePollingFrequency, resourcePollingFrequency);
144 }
145 }
146
147 loadContext();
148 } catch (ResourceException e) {
149 throw new ServiceException("Unable to initialize service: " + getId(), e);
150 }
151 }
152
153
154 public void reload() throws ServiceException {
155 log.debug("Reloading service {}", getId());
156 loadContext();
157 }
158
159
160 public void destroy() throws ServiceException {
161 pollingTimer.cancel();
162 super.destroy();
163 }
164
165
166 protected class ConfigurationResourceListener implements ResourceChangeListener {
167
168
169 public void onResourceCreate(Resource resource) {
170 try {
171 loadContext();
172 } catch (ServiceException e) {
173 log.error(
174 "Error reloading configuration, upon configuration resource creation, for service " + getId(),
175 e);
176 }
177 }
178
179
180 public void onResourceDelete(Resource resource) {
181 try {
182 loadContext();
183 } catch (ServiceException e) {
184 log.error(
185 "Error reloading configuration, upon configuration resource deletion, for service " + getId(),
186 e);
187 }
188 }
189
190
191 public void onResourceUpdate(Resource resource) {
192 try {
193 loadContext();
194 } catch (ServiceException e) {
195 log.error("Error reloading configuration, upon configuration resource update, for service " + getId(),
196 e);
197 }
198 }
199 }
200 }