]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.osgi.boot/src/org/argeo/osgi/boot/a2/ProvisioningManager.java
Add reference to git.argeo.org
[lgpl/argeo-commons.git] / org.argeo.osgi.boot / src / org / argeo / osgi / boot / a2 / ProvisioningManager.java
1 package org.argeo.osgi.boot.a2;
2
3 import java.io.InputStream;
4 import java.net.URI;
5 import java.nio.file.Path;
6 import java.nio.file.Paths;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.argeo.osgi.boot.OsgiBootException;
17 import org.argeo.osgi.boot.OsgiBootUtils;
18 import org.eclipse.osgi.launch.EquinoxFactory;
19 import org.osgi.framework.Bundle;
20 import org.osgi.framework.BundleContext;
21 import org.osgi.framework.BundleException;
22 import org.osgi.framework.Constants;
23 import org.osgi.framework.Version;
24 import org.osgi.framework.launch.Framework;
25 import org.osgi.framework.launch.FrameworkFactory;
26 import org.osgi.framework.wiring.FrameworkWiring;
27
28 public class ProvisioningManager {
29 BundleContext bc;
30 OsgiContext osgiContext;
31 List<ProvisioningSource> sources = Collections.synchronizedList(new ArrayList<>());
32
33 public ProvisioningManager(BundleContext bc) {
34 this.bc = bc;
35 osgiContext = new OsgiContext(bc);
36 osgiContext.load();
37 }
38
39 void addSource(ProvisioningSource context) {
40 sources.add(context);
41 }
42
43 void installWholeSource(ProvisioningSource context) {
44 Set<Bundle> updatedBundles = new HashSet<>();
45 for (A2Contribution contribution : context.contributions.values()) {
46 for (A2Component component : contribution.components.values()) {
47 A2Module module = component.last().last();
48 Bundle bundle = installOrUpdate(module);
49 if (bundle != null)
50 updatedBundles.add(bundle);
51 }
52 }
53 FrameworkWiring frameworkWiring = bc.getBundle(0).adapt(FrameworkWiring.class);
54 frameworkWiring.refreshBundles(updatedBundles);
55 }
56
57 public void registerSource(String uri) {
58 try {
59 URI u = new URI(uri);
60 if ("a2".equals(u.getScheme())) {
61 if (u.getHost() == null || "".equals(u.getHost())) {
62 Path base = Paths.get(u.getPath());
63 FsA2Source source = new FsA2Source(base);
64 source.load();
65 addSource(source);
66 }
67 }
68 } catch (Exception e) {
69 throw new OsgiBootException("Cannot add source " + uri, e);
70 }
71 }
72
73 public boolean registerDefaultSource() {
74 String frameworkLocation = bc.getProperty("osgi.framework");
75 try {
76 URI frameworkLocationUri = new URI(frameworkLocation);
77 if ("file".equals(frameworkLocationUri.getScheme())) {
78 Path frameworkPath = Paths.get(frameworkLocationUri);
79 if (frameworkPath.getParent().getFileName().toString().equals(A2Contribution.BOOT)) {
80 Path base = frameworkPath.getParent().getParent();
81 URI baseUri = new URI("a2", null, null, 0, base.toString(), null, null);
82 registerSource(baseUri.toString());
83 OsgiBootUtils.info("Registered " + baseUri + " as default source");
84 return true;
85 }
86 }
87 } catch (Exception e) {
88 OsgiBootUtils.error("Cannot register default source based on framework location " + frameworkLocation, e);
89 }
90 return false;
91 }
92
93 public void install(String spec) {
94 if (spec == null) {
95 for (ProvisioningSource source : sources) {
96 installWholeSource(source);
97 }
98 }
99 }
100
101 /** @return the new/updated bundle, or null if nothign was done. */
102 Bundle installOrUpdate(A2Module module) {
103 try {
104 ProvisioningSource moduleSource = module.getBranch().getComponent().getContribution().getSource();
105 Version moduleVersion = module.getVersion();
106 A2Branch osgiBranch = osgiContext.findBranch(module.getBranch().getComponent().getId(), moduleVersion);
107 if (osgiBranch == null) {
108 Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
109 moduleSource.newInputStream(module.getLocator()));
110 if (OsgiBootUtils.isDebug())
111 OsgiBootUtils.debug("Installed bundle " + bundle.getLocation() + " with version " + moduleVersion);
112 return bundle;
113 } else {
114 A2Module lastOsgiModule = osgiBranch.last();
115 int compare = moduleVersion.compareTo(lastOsgiModule.getVersion());
116 if (compare > 0) {// update
117 Bundle bundle = (Bundle) lastOsgiModule.getLocator();
118 bundle.update(moduleSource.newInputStream(module.getLocator()));
119 OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
120 return bundle;
121 }
122 }
123 } catch (Exception e) {
124 OsgiBootUtils.error("Could not install module " + module, e);
125 }
126 return null;
127 }
128
129 public Collection<Bundle> update() {
130 boolean fragmentsUpdated = false;
131 Set<Bundle> updatedBundles = new HashSet<>();
132 bundles: for (Bundle bundle : bc.getBundles()) {
133 for (ProvisioningSource source : sources) {
134 String componentId = bundle.getSymbolicName();
135 Version version = bundle.getVersion();
136 A2Branch branch = source.findBranch(componentId, version);
137 if (branch == null)
138 continue bundles;
139 A2Module module = branch.last();
140 Version moduleVersion = module.getVersion();
141 int compare = moduleVersion.compareTo(version);
142 if (compare > 0) {// update
143 try (InputStream in = source.newInputStream(module.getLocator())) {
144 bundle.update(in);
145 String fragmentHost = bundle.getHeaders().get(Constants.FRAGMENT_HOST);
146 if (fragmentHost != null)
147 fragmentsUpdated = true;
148 OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
149 updatedBundles.add(bundle);
150 } catch (Exception e) {
151 OsgiBootUtils.error("Cannot update with module " + module, e);
152 }
153 }
154 }
155 }
156 FrameworkWiring frameworkWiring = bc.getBundle(0).adapt(FrameworkWiring.class);
157 if (fragmentsUpdated)// refresh all
158 frameworkWiring.refreshBundles(null);
159 else
160 frameworkWiring.refreshBundles(updatedBundles);
161 return updatedBundles;
162 }
163
164 private static Framework launch() {
165 // start OSGi
166 FrameworkFactory frameworkFactory = new EquinoxFactory();
167 Map<String, String> configuration = new HashMap<>();
168 configuration.put("osgi.console", "2323");
169 Framework framework = frameworkFactory.newFramework(configuration);
170 try {
171 framework.start();
172 } catch (BundleException e) {
173 throw new OsgiBootException("Cannot start OSGi framework", e);
174 }
175 return framework;
176 }
177
178 public static void main(String[] args) {
179 Framework framework = launch();
180 try {
181 ProvisioningManager pm = new ProvisioningManager(framework.getBundleContext());
182 FsA2Source context = new FsA2Source(Paths.get(
183 "/home/mbaudier/dev/git/apache2/argeo-commons/dist/argeo-node/target/argeo-node-2.1.74-SNAPSHOT/argeo-node/share/osgi"));
184 context.load();
185 if (framework.getBundleContext().getBundles().length == 1) {// initial
186 pm.install(null);
187 } else {
188 pm.update();
189 }
190 } catch (Exception e) {
191 e.printStackTrace();
192 } finally {
193 try {
194 // framework.stop();
195 } catch (Exception e) {
196 e.printStackTrace();
197 }
198 }
199 }
200
201 }