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 log.info("{} service configuration reloaded", getId());
158 }
159
160
161 public void destroy() throws ServiceException {
162 pollingTimer.cancel();
163 super.destroy();
164 }
165
166
167 protected class ConfigurationResourceListener implements ResourceChangeListener {
168
169
170 public void onResourceCreate(Resource resource) {
171 try {
172 loadContext();
173 } catch (ServiceException e) {
174 log.error(
175 "Error reloading configuration, upon configuration resource creation, for service " + getId(),
176 e);
177 }
178 }
179
180
181 public void onResourceDelete(Resource resource) {
182 try {
183 loadContext();
184 } catch (ServiceException e) {
185 log.error(
186 "Error reloading configuration, upon configuration resource deletion, for service " + getId(),
187 e);
188 }
189 }
190
191
192 public void onResourceUpdate(Resource resource) {
193 try {
194 loadContext();
195 } catch (ServiceException e) {
196 log.error("Error reloading configuration, upon configuration resource update, for service " + getId(),
197 e);
198 }
199 }
200 }
201 }