Using multiple configuration files in OSGi with equinox launcher - osgi

I want to use separate configuration files for different bundles instead of using a single configuration/config.ini file. I am following this doc https://www.eclipse.org/equinox/documents/quickstart-framework.php .
I am not able to figure out how to achieve this. Any suggestion would be very helpful.
Thanks in advance.

Following links solve the problem I was facing-
https://www.eclipse.org/forums/index.php/t/1072082/
https://git.eclipse.org/c/om2m/org.eclipse.om2m.git/tree/org.eclipse.om2m.site.mn-cse/configurations/services/lifx.basedriver.properties
https://git.eclipse.org/c/om2m/org.eclipse.om2m.git/tree/org.eclipse.om2m.sdt/org.eclipse.om2m.sdt.home.lifx/src/main/java/org/eclipse/om2m/sdt/home/lifx/impl/Activator.java
Steps I followed to achieve this -
Create configurations/services/<config_file_name>.properties having configurations in key-value pair. For example - property1 property1_value
Import package org.osgi.service.cm for your bundle
Use the following code
package <package_name>;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
public class Activator implements BundleActivator, ManagedService {
private static BundleContext context;
private ServiceRegistration managedServiceServiceRegistration;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
Dictionary properties = new Hashtable<>();
properties.put(Constants.SERVICE_PID, "config_file_name");
managedServiceServiceRegistration =
bundleContext.registerService(ManagedService.class.getName(), this, properties);
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}
#Override
public void updated(Dictionary properties) throws ConfigurationException {
try {
System.out.println(properties.get("property1"));
} catch (Exception e) {
e.printStackTrace();
}
}
}

Related

java.lang.NullPointerException at java.base/sun.nio.fs.UnixPath.normalizeAndCheck(UnixPath.java:75) in SpringApplication

I've spring-data-aerospike project at github in branch npe.
The application.properties is
aerospike.host=localhost
aerospike.port=3000
aerospike.namespace=test
aerospike.timeout=125
os.name=Linux
line.separator=\n
The spring ApplicationContext is
mport com.aerospike.demo.simplespringbootaerospikedemo.repositories.AerospikeUserRepository;
import com.aerospike.client.Host;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.aerospike.config.AbstractAerospikeDataConfiguration;
import org.springframework.data.aerospike.repository.config.EnableAerospikeRepositories;
import java.util.Collection;
import java.util.Collections;
#Configuration
#EnableConfigurationProperties(AerospikeConfigurationProperties.class)
#EnableAerospikeRepositories(basePackageClasses = AerospikeUserRepository.class)
public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
#Autowired
private AerospikeConfigurationProperties aerospikeConfigurationProperties;
#Override
protected Collection<Host> getHosts() {
return Collections.singleton(new Host(aerospikeConfigurationProperties.getHost(), aerospikeConfigurationProperties.getPort()));
}
#Override
protected String nameSpace() {
return aerospikeConfigurationProperties.getNamespace();
}
}
The main application is -
import com.aerospike.demo.simplespringbootaerospikedemo.configuration.AerospikeConfiguration;
import com.aerospike.demo.simplespringbootaerospikedemo.objects.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.aerospike.core.AerospikeTemplate;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.stream.Stream;
import org.joda.time.DateTime;
public class TestSpringConfig {
public static void main(String[] args) throws IOException {
System.out.println(ClassLoader.getSystemResourceAsStream("application.properties").available());
Properties props = new Properties();
InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream("application.properties");
if (resourceAsStream != null) {
props.load(resourceAsStream);
}
if(props != null) {
System.setProperties(props);
}
try {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AerospikeConfiguration.class);
AerospikeTemplate template = ctx.getBean(AerospikeTemplate.class);
template.save(new User(123, "","", 12, DateTime.now().plusSeconds(60).getMillis()));
} catch (Exception e) {
StackTraceElement[] st = e.getStackTrace();
Stream.of(st).forEach(System.out::println);
} catch (ExceptionInInitializerError e) {
System.out.println(e.getCause());
e.getCause().printStackTrace();
}
}
}
when I run the main application I get below error -
java.lang.NullPointerException
at java.base/sun.nio.fs.UnixPath.normalizeAndCheck(UnixPath.java:75)
at java.base/sun.nio.fs.UnixPath.(UnixPath.java:69)
at java.base/sun.nio.fs.UnixFileSystem.getPath(UnixFileSystem.java:279)
at java.base/java.io.FilePermission.(FilePermission.java:207)
at java.base/sun.security.provider.PolicyFile.getKnownPermission(PolicyFile.java:886)
at java.base/sun.security.provider.PolicyFile.getInstance(PolicyFile.java:836)
at java.base/sun.security.provider.PolicyFile.addGrantEntry(PolicyFile.java:735)
at java.base/sun.security.provider.PolicyFile.initDefaultPolicy(PolicyFile.java:491)
at java.base/sun.security.provider.PolicyFile$2.run(PolicyFile.java:338)
at java.base/sun.security.provider.PolicyFile$2.run(PolicyFile.java:335)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:335)
at java.base/sun.security.provider.PolicyFile.init(PolicyFile.java:328)
at java.base/sun.security.provider.PolicyFile.(PolicyFile.java:281)
at java.base/java.security.Policy.loadPolicyProvider(Policy.java:207)
at java.base/java.security.Policy.getPolicyNoCheck(Policy.java:178)
at java.base/java.security.ProtectionDomain.implies(ProtectionDomain.java:321)
at java.base/java.security.ProtectionDomain.impliesWithAltFilePerm(ProtectionDomain.java:353)
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
at java.base/java.security.AccessController.checkPermission(AccessController.java:897)
at ch.qos.logback.core.util.Loader$1.run(Loader.java:48)
at ch.qos.logback.core.util.Loader$1.run(Loader.java:45)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at ch.qos.logback.core.util.Loader.(Loader.java:45)
at ch.qos.logback.classic.util.ContextInitializer.findURLOfDefaultConfigurationFile(ContextInitializer.java:109)
at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:138)
at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
at org.slf4j.impl.StaticLoggerBinder.(StaticLoggerBinder.java:55)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:417)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362)
at org.apache.commons.logging.LogAdapter$Slf4jAdapter.createLocationAwareLog(LogAdapter.java:130)
at org.apache.commons.logging.LogAdapter.createLog(LogAdapter.java:91)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:67)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:59)
at org.springframework.context.support.AbstractApplicationContext.(AbstractApplicationContext.java:178)
at org.springframework.context.support.GenericApplicationContext.(GenericApplicationContext.java:112)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:67)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:91)
at com.aerospike.demo.simplespringbootaerospikedemo.TestSpringConfig.main(TestSpringConfig.java:27)
Any idea how to fix this error?
The workaround that you tried to implement in order to "Autowire" AerospikeTemplate bean doesn't work and results in a NPE. There are a few ways to "Autowire" a bean (in this case an AerospikeTemplate bean) in the static main() method, here is a StackOverFlow question that talks about this scenario:
How to use autowired (#Autowired) references from main(String[] args) method?
But the main question is what are you trying to achieve? the conventional way of using Spring Data Aerospike Repository/Template is to Autowire the repository/template in a service (also a bean) and then call the service methods from something like a controller/test/different service etc... Most Spring applications doesn't include logic inside the static main() method - it can be done but it doesn't make much sense.
To autowire AerospikeTemplate you need to setup Spring Boot application in the main method (check an example here):
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
then you can autowire AerospikeTemplate anywhere you need.
If you are developing a console application using Spring Boot I would suggest using org.springframework.boot.CommandLineRunner. For example:
#Component
public class CommandLineRunnerImpl implements CommandLineRunner {
#Autowired
AerospikeTemplate template;
#Override
public void run(String... args) throws Exception {
template.save(new User(123, "","", 12, DateTime.now().plusSeconds(60).getMillis()));
}
}

Open tracer Jaeger Trace not getting reflect for apache camel

I am new to apache camel and open tracing with Jaeger, I trying to get the traces for apache camel in Jaeger UI but its not getting captured through Open Tracing.
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.springframework.stereotype.Component;
#Component
public class RouteBuilderClient {
public void test() throws Exception {
DefaultCamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("timer:first-timer")
.to("log:first-timer");
}
});
camelContext.start();
camelContext.stop();
}
}
However if if I extend the RouteBuilder class(Below is the sample code) and then I override the configure method then traces are getting generated for Apache camel. Is there any way without extending the routeBuilder I can get the traces?
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class RouteBuilderClient extends RouteBuilder {
#Override
public void configure() throws Exception {
from("timer:first-timer")
.to("log:first-timer");
}
}
My controller class:
import org.apache.camel.opentracing.starter.CamelOpenTracing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#CamelOpenTracing
public class JaegarClientApplication {
public static void main(String[] args) {
SpringApplication.run(JaegarClientApplication.class, args);
}
}
Try adding this in your setup() method, before starting the Camel context:
OpenTracingTracer ottracer = new OpenTracingTracer();
ottracer.init(camelContext);
camelContext.start();
Below is my code that Worked successfully.
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.opentracing.OpenTracingTracer;
public class RouteBuilderClient3 {
public void test() throws Exception {
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("timer:first-timer3").transform().constant("Rajesh client 3")
.to("log:first-timer3");
}
};
CamelContext myCamelContext = new DefaultCamelContext();
myCamelContext.addRoutes(builder);
OpenTracingTracer ottracer = new OpenTracingTracer();
ottracer.init(myCamelContext);
myCamelContext.start();
// myCamelContext.stop();
}
}

how to overload Spring PropertyPlaceholderConfigurer's processProperties() method

My requirement is as given below :
"we have a load a big properties file using Spring and then loop through it .
While looping we have to check the very first column of properties file for some particular values.
As soon as we find those values we have to print that value and continue this printing process till the very end."
For this i finally able to build a code like below :
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringPropertiesUtil extends PropertyPlaceholderConfigurer {
private static Map<String, String> propertiesMap;
private static String keyToFind = "myProperty";
// Default as in PropertyPlaceholderConfigurer
private int springSystemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;
#Override
public void setSystemPropertiesMode(int systemPropertiesMode) {
super.setSystemPropertiesMode(systemPropertiesMode);
springSystemPropertiesMode = systemPropertiesMode;
}
#Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
super.processProperties(beanFactory, props);
for (Object key : props.keySet()) {
String keyStr = key.toString();
if(keyStr.equals(keyToFind)) {
String valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode);
System.out.println(valueStr);
}
}
}
public String getProperty(String name) {
return propertiesMap.get(name).toString();
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
((ConfigurableApplicationContext)context).close();
}
}
It is working fine but i am finding a nicer way of doing this if i can overload processProperties() and can pass String keyTofind to this method rather than defining it globally.
Any suggestion is welcome.
Thanks.
Alternatively to your solution, you could implement a custom property source. I believe this is the mechanism Spring has intended for proprietary "source parsing logic".
The subject is not terribly well documented on the web, but this article gives some insight: http://scottfrederick.cfapps.io/blog/2012/05/22/Custom-PropertySource-in-Spring-3.1---Part-1/

Copying a file to HDFS2 via camel doesn't work

Does anyone have a good example of writing files to hdfs2 via camel?
I tried the following code :
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
public final class Main {
private Main() {
}
public static void main(String args[]) throws Exception {
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() {
from("file:C:\\FILES\\SRC\\2015-03-31_16-58-56.png?noop=true")
.to("hdfs2://xxxx:9000/testCamel/D2/qwe.png");
//.to("file:C:\\FILES\\OUT");
}
});
//ProducerTemplate template = context.createProducerTemplate();
context.start();
context.stop();
}
}
The files are created in HDFS but all of them are empty (0 bytes).
make sure noop=false when you consume from a file to HDFS. hdfs component uses chunk to consume, so if noop is true, camel will think that it already consumed it.

Problem investigating JmDNS3.4.1 jar

I'm newbie here. I'm dealing with my first program using osgi bundles and JmDNS. After adding JmDNS 3.4.1 jar to my project, I'm testing the following basic code:
My Activator:
package test.discoverservice;
import java.io.IOException;
import test.DiscoverServices;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceTypeListener;
import org.equinoxosgi.jmdns.dev.discoverservice.DiscoverServices.SampleListener;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class JmdnsActivator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Launching");
try {
System.out.println("step 1");
final JmDNS jmdns = JmDNS.create();
System.out.println("step 2");
jmdns.addServiceListener("_http._tcp.local.", new SampleListener());
// jmdns.close();
// System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
public void stop(BundleContext context) throws Exception {
System.out.println("Terminating");
}
}
and here is the bundle:
package test.discoverservice;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;
public class DiscoverServices {
static class SampleListener implements ServiceListener {
#Override
public void serviceAdded(ServiceEvent event) {
System.out.println("Service added : " + event.getName() + "." + event.getType());
}
#Override
public void serviceRemoved(ServiceEvent event) {
System.out.println("Service removed : " + event.getName() + "." + event.getType());
}
#Override
public void serviceResolved(ServiceEvent event) {
System.out.println("Service resolved: " + event.getInfo());
}
}
}
when I run the code, I get :
osgi> Launching
step 1
and then it stops, so I guess there is a probelm with the creation of the JmDNS instance..
Any idea please?
Note that if I don't use a bundle with an activator (simple program with main) everything works properly
import java.io.IOException;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceTypeListener;
public class DiscoverServiceTypes {
static class SampleListener implements ServiceTypeListener {
#Override
public void serviceTypeAdded(ServiceEvent event) {
System.out.println("Service type added: " + event.getType());
}
public void subTypeForServiceTypeAdded(ServiceEvent event) {
System.out.println("SubType for service type added: " + event.getType());
}
}
public static void main(String[] args) {
try {
JmDNS jmdns = JmDNS.create();
System.out.println("JmDNS created !!");
jmdns.addServiceTypeListener(new SampleListener());
// jmdns.close();
// System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
PS: I'm running it on Windows
You have to add the imported library in the classpath of the MANIFEST.MF file of the OSGI Framework if not already done.
Bundle-ClassPath: org.json.jar,
lib/jmdns-3.4.1.jar, ...
If you got the lirary from sourceforge check if the jar file is correct and no class is present twice in the jar. (If so, just use the .jar from Maven)

Resources