]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/admin/MinimalBundlesManager.java
Ignore log files
[gpl/argeo-slc.git] / runtime / org.argeo.slc.detached / src / main / java / org / argeo / slc / detached / admin / MinimalBundlesManager.java
1 package org.argeo.slc.detached.admin;
2
3 import org.osgi.framework.Bundle;
4 import org.osgi.framework.BundleContext;
5 import org.osgi.framework.BundleException;
6 import org.osgi.framework.FrameworkEvent;
7 import org.osgi.framework.FrameworkListener;
8 import org.osgi.framework.InvalidSyntaxException;
9 import org.osgi.framework.ServiceReference;
10 import org.osgi.service.packageadmin.PackageAdmin;
11
12 /**
13 * Wraps low-level access to a {@link BundleContext}. Hacked from the related
14 * class in org.argeo.slc.support.osgi.
15 */
16 class MinimalBundlesManager implements FrameworkListener {
17 private final BundleContext bundleContext;
18
19 private long defaultTimeout = 10000l;
20 private final Object refreshedPackageSem = new Object();
21
22 private boolean debug = true;
23
24 public MinimalBundlesManager(BundleContext bundleContext) {
25 this.bundleContext = bundleContext;
26 bundleContext.addFrameworkListener(this);
27 }
28
29 protected void finalize() throws Throwable {
30 bundleContext.removeFrameworkListener(this);
31 }
32
33 /**
34 * Stop the module, update it, refresh it and restart it. All synchronously.
35 */
36 public void upgradeSynchronous(Bundle bundle) {
37 try {
38 stopSynchronous(bundle);
39 updateSynchronous(bundle);
40 // Refresh in case there are fragments
41 refreshSynchronous(bundle);
42 startSynchronous(bundle);
43
44 String filter = "(Bundle-SymbolicName=" + bundle.getSymbolicName()
45 + ")";
46 // Wait for application context to be ready
47 // TODO: use service tracker
48 getServiceRefSynchronous(
49 "org.springframework.context.ApplicationContext", filter);
50
51 if (debug)
52 debug("Bundle " + bundle.getSymbolicName()
53 + " ready to be used at latest version.");
54 } catch (Exception e) {
55 throw new RuntimeException("Cannot update bundle "
56 + bundle.getSymbolicName(), e);
57 }
58 }
59
60 /** Updates bundle synchronously. */
61 protected void updateSynchronous(Bundle bundle) throws BundleException {
62 // int originalState = bundle.getState();
63 bundle.update();
64 boolean waiting = true;
65
66 long begin = System.currentTimeMillis();
67 do {
68 int state = bundle.getState();
69 if (state == Bundle.INSTALLED || state == Bundle.ACTIVE
70 || state == Bundle.RESOLVED)
71 waiting = false;
72
73 sleep(100);
74 if (System.currentTimeMillis() - begin > defaultTimeout)
75 throw new RuntimeException("Update of bundle "
76 + bundle.getSymbolicName()
77 + " timed out. Bundle state = " + bundle.getState());
78 } while (waiting);
79
80 if (debug)
81 debug("Bundle " + bundle.getSymbolicName() + " updated.");
82 }
83
84 /** Starts bundle synchronously. Does nothing if already started. */
85 protected void startSynchronous(Bundle bundle) throws BundleException {
86 int originalState = bundle.getState();
87 if (originalState == Bundle.ACTIVE)
88 return;
89
90 bundle.start();
91 boolean waiting = true;
92
93 long begin = System.currentTimeMillis();
94 do {
95 if (bundle.getState() == Bundle.ACTIVE)
96 waiting = false;
97
98 sleep(100);
99 if (System.currentTimeMillis() - begin > defaultTimeout)
100 throw new RuntimeException("Start of bundle "
101 + bundle.getSymbolicName()
102 + " timed out. Bundle state = " + bundle.getState());
103 } while (waiting);
104
105 if (debug)
106 debug("Bundle " + bundle.getSymbolicName() + " started.");
107 }
108
109 /** Stops bundle synchronously. Does nothing if already started. */
110 protected void stopSynchronous(Bundle bundle) throws BundleException {
111 int originalState = bundle.getState();
112 if (originalState != Bundle.ACTIVE)
113 return;
114
115 bundle.stop();
116 boolean waiting = true;
117
118 long begin = System.currentTimeMillis();
119 do {
120 if (bundle.getState() != Bundle.ACTIVE
121 && bundle.getState() != Bundle.STOPPING)
122 waiting = false;
123
124 sleep(100);
125 if (System.currentTimeMillis() - begin > defaultTimeout)
126 throw new RuntimeException("Stop of bundle "
127 + bundle.getSymbolicName()
128 + " timed out. Bundle state = " + bundle.getState());
129 } while (waiting);
130
131 if (debug)
132 debug("Bundle " + bundle.getSymbolicName() + " stopped.");
133 }
134
135 /** Refresh bundle synchronously. Does nothing if already started. */
136 protected void refreshSynchronous(Bundle bundle) throws BundleException {
137 ServiceReference packageAdminRef = bundleContext
138 .getServiceReference(PackageAdmin.class.getName());
139 PackageAdmin packageAdmin = (PackageAdmin) bundleContext
140 .getService(packageAdminRef);
141 Bundle[] bundles = { bundle };
142 packageAdmin.refreshPackages(bundles);
143
144 synchronized (refreshedPackageSem) {
145 try {
146 refreshedPackageSem.wait(defaultTimeout);
147 } catch (InterruptedException e) {
148 // silent
149 }
150 }
151
152 if (debug)
153 debug("Bundle " + bundle.getSymbolicName() + " refreshed.");
154 }
155
156 public void frameworkEvent(FrameworkEvent event) {
157 if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
158 synchronized (refreshedPackageSem) {
159 refreshedPackageSem.notifyAll();
160 }
161 }
162 }
163
164 public ServiceReference[] getServiceRefSynchronous(String clss,
165 String filter) throws InvalidSyntaxException {
166 if (debug)
167 debug("Filter: '" + filter + "'");
168 ServiceReference[] sfs = null;
169 boolean waiting = true;
170 long begin = System.currentTimeMillis();
171 do {
172 sfs = bundleContext.getServiceReferences(clss, filter);
173
174 if (sfs != null)
175 waiting = false;
176
177 sleep(100);
178 if (System.currentTimeMillis() - begin > defaultTimeout)
179 throw new RuntimeException("Search of services " + clss
180 + " with filter " + filter + " timed out.");
181 } while (waiting);
182
183 return sfs;
184 }
185
186 /*
187 * protected void sleep(long ms) { try { Thread.sleep(ms); } catch
188 * (InterruptedException e) { // silent } }
189 *
190 * public ServiceTracker newTracker(Class<?> clss) { ServiceTracker st = new
191 * ServiceTracker(bundleContext, clss.getName(), null); st.open(); return
192 * st; }
193 *
194 * @SuppressWarnings(value = { "unchecked" }) public <T> T
195 * getSingleService(Class<T> clss, String filter) {
196 * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
197 * ServiceReference[] sfs; try { sfs =
198 * bundleContext.getServiceReferences(clss.getName(), filter); } catch
199 * (InvalidSyntaxException e) { throw new
200 * SlcException("Cannot retrieve service reference for " + filter, e); }
201 *
202 * if (sfs == null || sfs.length == 0) return null; else if (sfs.length > 1)
203 * throw new SlcException("More than one execution flow found for " +
204 * filter); return (T) bundleContext.getService(sfs[0]); }
205 *
206 * public <T> T getSingleServiceStrict(Class<T> clss, String filter) { T
207 * service = getSingleService(clss, filter); if (service == null) throw new
208 * SlcException("No execution flow found for " + filter); else return
209 * service; }
210 *
211 * public Bundle findRelatedBundle(OsgiBundle osgiBundle) { Bundle bundle =
212 * null; if (osgiBundle.getInternalBundleId() != null) { bundle =
213 * bundleContext.getBundle(osgiBundle.getInternalBundleId()); Assert.isTrue(
214 * osgiBundle.getName().equals(bundle.getSymbolicName()),
215 * "symbolic name consistent");
216 * Assert.isTrue(osgiBundle.getVersion().equals(
217 * bundle.getHeaders().get(Constants.BUNDLE_VERSION)),
218 * "version consistent"); } else { for (Bundle b :
219 * bundleContext.getBundles()) { if
220 * (b.getSymbolicName().equals(osgiBundle.getName())) { if
221 * (b.getHeaders().get(Constants.BUNDLE_VERSION).equals(
222 * osgiBundle.getVersion())) { bundle = b;
223 * osgiBundle.setInternalBundleId(b.getBundleId()); } } } } return bundle; }
224 *
225 * public OsgiBundle findFromPattern(String pattern) { OsgiBundle osgiBundle
226 * = null; for (Bundle b : bundleContext.getBundles()) { if
227 * (b.getSymbolicName().contains(pattern)) { osgiBundle = new OsgiBundle(b);
228 * break; } } return osgiBundle; }
229 *
230 * public OsgiBundle getBundle(Long bundleId) { Bundle bundle =
231 * bundleContext.getBundle(bundleId); return new OsgiBundle(bundle); }
232 *
233 * public void setBundleContext(BundleContext bundleContext) {
234 * this.bundleContext = bundleContext; }
235 *
236 * public void afterPropertiesSet() throws Exception {
237 * bundleContext.addFrameworkListener(this); }
238 *
239 * public void setDefaultTimeout(Long defaultTimeout) { this.defaultTimeout
240 * = defaultTimeout; }
241 *
242 * BundleContext getBundleContext() { return bundleContext; }
243 */
244
245 protected void debug(Object obj) {
246 if (debug)
247 System.out.println("#OSGiMANAGER DEBUG# " + obj);
248 }
249
250 protected void sleep(long ms) {
251 try {
252 Thread.sleep(ms);
253 } catch (InterruptedException e) {
254 // silent
255 }
256 }
257
258 }