blob: cbe0e7936d054c5faf4e47a48fefc4ffac7ce054 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.dosgi.discovery.zookeeper.server.config;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ManagedService;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Activator implements BundleActivator {
private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
private static final String ZOOKEEPER_PORT = "org.apache.cxf.dosgi.discovery.zookeeper.port";
private static final String PID = "org.apache.cxf.dosgi.discovery.zookeeper.server";
private ServiceTracker st;
public void start(BundleContext context) throws Exception {
synchronized (Activator.class) {
// Only one thread gets to set the port number
if (System.getProperty(ZOOKEEPER_PORT) == null) {
String port = getFreePort();
System.setProperty(ZOOKEEPER_PORT, port);
LOG.info("Global ZooKeeper port: {}", port);
}
}
st = new ServiceTracker(context, ConfigurationAdmin.class.getName(), null) {
@Override
public Object addingService(ServiceReference reference) {
Object svc = super.addingService(reference);
if (svc instanceof ConfigurationAdmin) {
try {
ConfigurationAdmin cadmin = (ConfigurationAdmin) svc;
Configuration cfg = cadmin.getConfiguration(PID, null);
Dictionary<String, Object> props = new Hashtable<String, Object>();
String zp = System.getProperty(ZOOKEEPER_PORT);
props.put("clientPort", zp);
cfg.update(props);
LOG.debug("Set ZooKeeper client port to {}", zp);
} catch (IOException e) {
LOG.error("Failed to configure ZooKeeper server!", e);
}
}
return svc;
}
};
st.open();
// The following section is done synchronously otherwise it doesn't happen in time for the CT
ServiceReference[] refs = context.getServiceReferences(ManagedService.class.getName(),
"(service.pid=org.apache.cxf.dosgi.discovery.zookeeper)");
if (refs == null || refs.length == 0) {
throw new RuntimeException("This bundle must be started after the bundle with the ZooKeeper "
+ "Discovery Managed Service was started.");
}
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put("zookeeper.host", "127.0.0.1");
props.put("zookeeper.port", System.getProperty(ZOOKEEPER_PORT));
ManagedService ms = (ManagedService) context.getService(refs[0]);
try {
ms.updated(props);
} finally {
if (ms != null) {
context.ungetService(refs[0]);
}
}
LOG.debug("Passed the zookeeper.host property to the ZooKeeper Client managed service.");
}
private String getFreePort() {
try {
ServerSocket ss = new ServerSocket(0);
String port = "" + ss.getLocalPort();
ss.close();
return port;
} catch (IOException e) {
LOG.error("Failed to find a free port!", e);
return null;
}
}
public void stop(BundleContext context) throws Exception {
st.close();
}
}