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