import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
-public class CmsDeployment implements NodeDeployment, SynchronousConfigurationListener {
+public class CmsDeployment implements NodeDeployment {
private final Log log = LogFactory.getLog(getClass());
private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
- private Path deployPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_PATH);
- private SortedMap<LdapName, Attributes> deployConfigs = new TreeMap<>();
-
+ private final DeployConfig deployConfig;
// private Repository deployedNodeRepository;
private HomeRepository homeRepository;
private Long availableSince;
public CmsDeployment() {
- ConfigurationAdmin configurationAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class));
// FIXME no guarantee this is already available
NodeState nodeState = bc.getService(bc.getServiceReference(NodeState.class));
- try {
- initDeployConfigs(configurationAdmin, nodeState);
- } catch (IOException e) {
- throw new CmsException("Could not init deploy configs", e);
- }
- bc.registerService(SynchronousConfigurationListener.class, this, null);
+ deployConfig = new DeployConfig(nodeState.isClean());
new ServiceTracker<>(bc, RepositoryContext.class, new RepositoryContextStc()).open();
}
- private void initDeployConfigs(ConfigurationAdmin configurationAdmin, NodeState nodeState) throws IOException {
- if (!Files.exists(deployPath)) {// first init
- Files.createDirectories(deployPath.getParent());
- Files.createFile(deployPath);
- FirstInitProperties firstInitProperties = new FirstInitProperties();
-
- Dictionary<String, Object> nodeConfig = firstInitProperties.getNodeRepositoryConfig();
- // node repository is mandatory
- putFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
-
- Dictionary<String, Object> webServerConfig = firstInitProperties.getHttpServerConfig();
- if (!webServerConfig.isEmpty())
- putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
-
- saveDeployedConfigs();
- }
-
- try (InputStream in = Files.newInputStream(deployPath)) {
- deployConfigs = new LdifParser().read(in);
- }
- if (nodeState.isClean()) {
- for (LdapName dn : deployConfigs.keySet()) {
- Rdn lastRdn = dn.getRdn(dn.size() - 1);
- LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1);
- if (prefix.toString().equals(NodeConstants.DEPLOY_BASEDN)) {
- if (lastRdn.getType().equals(NodeConstants.CN)) {
- // service
- String pid = lastRdn.getValue().toString();
- Configuration conf = configurationAdmin.getConfiguration(pid);
- AttributesDictionary dico = new AttributesDictionary(deployConfigs.get(dn));
- conf.update(dico);
- } else {
- // service factory definition
- }
- } else {
- // service factory service
- Rdn beforeLastRdn = dn.getRdn(dn.size() - 2);
- assert beforeLastRdn.getType().equals(NodeConstants.OU);
- String factoryPid = beforeLastRdn.getValue().toString();
- Configuration conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null);
- AttributesDictionary dico = new AttributesDictionary(deployConfigs.get(dn));
- conf.update(dico);
- }
- }
- }
- // TODO check consistency if not clean
- }
-
- @Override
- public void configurationEvent(ConfigurationEvent event) {
- try {
- if (ConfigurationEvent.CM_UPDATED == event.getType()) {
- ConfigurationAdmin configurationAdmin = bc.getService(event.getReference());
- Configuration conf = configurationAdmin.getConfiguration(event.getPid(), null);
- LdapName serviceDn = null;
- String factoryPid = conf.getFactoryPid();
- if (factoryPid != null) {
- LdapName serviceFactoryDn = serviceFactoryDn(factoryPid);
- if (deployConfigs.containsKey(serviceFactoryDn)) {
- for (LdapName dn : deployConfigs.keySet()) {
- if (dn.startsWith(serviceFactoryDn)) {
- Rdn lastRdn = dn.getRdn(dn.size() - 1);
- assert lastRdn.getType().equals(NodeConstants.CN);
- Object value = conf.getProperties().get(lastRdn.getType());
- assert value != null;
- if (value.equals(lastRdn.getValue())) {
- serviceDn = dn;
- break;
- }
- }
- }
-
- Object cn = conf.getProperties().get(NodeConstants.CN);
- if (cn == null)
- throw new IllegalArgumentException("Properties must contain cn");
- if (serviceDn == null) {
- putFactoryDeployConfig(factoryPid, conf.getProperties());
- } else {
- Attributes attrs = deployConfigs.get(serviceDn);
- assert attrs != null;
- AttributesDictionary.copy(conf.getProperties(), attrs);
- }
- saveDeployedConfigs();
- if (log.isDebugEnabled())
- log.debug("Updated deploy config " + serviceDn(factoryPid, cn.toString()));
- } else {
- // ignore non config-registered service factories
- }
- } else {
- serviceDn = serviceDn(event.getPid());
- if (deployConfigs.containsKey(serviceDn)) {
- Attributes attrs = deployConfigs.get(serviceDn);
- assert attrs != null;
- AttributesDictionary.copy(conf.getProperties(), attrs);
- saveDeployedConfigs();
- if (log.isDebugEnabled())
- log.debug("Updated deploy config " + serviceDn);
- } else {
- // ignore non config-registered services
- }
- }
- }
- } catch (Exception e) {
- log.error("Could not handle configuration event", e);
- }
- }
-
- private void putFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
- Object cn = props.get(NodeConstants.CN);
- if (cn == null)
- throw new IllegalArgumentException("cn must be set in properties");
- LdapName serviceFactorydn = serviceFactoryDn(factoryPid);
- if (!deployConfigs.containsKey(serviceFactorydn))
- deployConfigs.put(serviceFactorydn, new BasicAttributes(NodeConstants.OU, factoryPid));
- LdapName serviceDn = serviceDn(factoryPid, cn.toString());
- Attributes attrs = new BasicAttributes();
- AttributesDictionary.copy(props, attrs);
- deployConfigs.put(serviceDn, attrs);
- }
-
- private void putDeployConfig(String servicePid, Dictionary<String, Object> props) {
- LdapName serviceDn = serviceDn(servicePid);
- Attributes attrs = new BasicAttributes(NodeConstants.CN, servicePid);
- AttributesDictionary.copy(props, attrs);
- deployConfigs.put(serviceDn, attrs);
- }
-
- void saveDeployedConfigs() throws IOException {
- try (Writer writer = Files.newBufferedWriter(deployPath)) {
- new LdifWriter(writer).write(deployConfigs);
- }
- }
-
- private LdapName serviceFactoryDn(String factoryPid) {
- try {
- return new LdapName(NodeConstants.OU + "=" + factoryPid + "," + NodeConstants.DEPLOY_BASEDN);
- } catch (InvalidNameException e) {
- throw new IllegalArgumentException("Cannot generate DN from " + factoryPid, e);
- }
- }
-
- private LdapName serviceDn(String servicePid) {
- try {
- return new LdapName(NodeConstants.CN + "=" + servicePid + "," + NodeConstants.DEPLOY_BASEDN);
- } catch (InvalidNameException e) {
- throw new IllegalArgumentException("Cannot generate DN from " + servicePid, e);
- }
- }
-
- private LdapName serviceDn(String factoryPid, String cn) {
- try {
- return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(NodeConstants.CN, cn));
- } catch (InvalidNameException e) {
- throw new IllegalArgumentException("Cannot generate DN from " + factoryPid + " and " + cn, e);
- }
- }
-
private void prepareNodeRepository(Repository deployedNodeRepository) {
if (availableSince != null) {
throw new CmsException("Deployment is already available");