Spring - how to load configuration from database? - database

I need to load configuration settings used in applicationContext.xml from relational database (PostgreSQL).
I followed this article http://www.codeproject.com/Articles/28893/Loading-Application-Properties-from-a-Database but it uses a deprecated "Spring Modules" jar file.
Is there some another technique how to achieve it? I use Spring 3.
My idea is to set only access setting to database (hostname, dbname, username, password) for creating a datasource and probably create some own handler class(?) for loading setting from DB. In applicationContext.xml I will use settings in the same way - ${foo.bar}.
Plesase share your experience and code examples with this topic and Spring 3.

Although it's no longer bundled in Spring 3 I don't see any reason why you can't use it. Just include
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-jakarta-commons</artifactId>
<version>0.8</version>
</dependency>
On your maven pom alongside with other Spring 3 dependencies and the setup as described in the tutorial should look alright.
If that produces specific error please post the details (incl. stack trace) so we can help investigate further

Related

Rest API integration using Apache camel

I am new to Apache Camel, I have requirement to integrate two systems using REST API using Apache camel. I will receive a JSON message on my apache camel rest api endpoint(from source system).This json will contain arrays, I have to extract each array content and post to another external api end point (target). So initially I tried to send incoming message to camel rest api as it is to the target external api endpoint. When I try that, then on application startup I get error. I searched for similar exception but couldn't find anything concrete as in most of the example, source of message was used as a timer component.
Can't we make a call to external rest api end point?
Camel version : 3.4.0
Spring boot : 2.3.1
My router builder code
restConfiguration()
.component("servlet").port(9090).host("localhost")
.dataFormatProperty("prettyPrint", "true");
rest().post("/incoming")
.consumes(MediaType.APPLICATION_JSON_VALUE)
.produces(MediaType.APPLICATION_JSON_VALUE)
.route()
.to("https://webhook.site/ff4a6f68-3b20-4bb2-afa1-c15ccae515ef");
Exception I am getting for target external endpoint
org.apache.camel.NoSuchEndpointException:
No endpoint could be found for:
https://webhook.site/ff4a6f68-3b20-4bb2-afa1-c15ccae515ef,
please check your classpath contains the needed Camel component jar.
Please let me know, where I am making mistake.
Thanks in advance.
Ani
You don't have camel-http as dependency so add the dependency with correct version
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
Since you are already using camel 3.x you might also want to consider using dynamic endpoint component, in case your destination URL is defined dynamically. For example:
from("direct:login")
.toD("http:myloginserver:8080/login?userid=${header.userName}");

Storing a .jks file in Fabric profile

In our Apache Camel project, we are consuming a rest service which requires a .jks file.
Currently we are storing .jks file in a physical location and referring to that in Camel project. But it can't be used always, as we may be having access to the Fuse Management Console only and not to the physical location accessible from management console.
Another option is to store key file within bundle, which is can't be employed because, certificate may change based on the environment.
In this scenario, what can be a better solution to store key file?
Note
One option about which I thought was, storing .jks file within fabric profile. But could n't find any way to do that. Is it possible to store a file in Fabric profile?
What about storing the .jks in a java package and reading it as a resource?
You bundle imports org.niyasc.jks and loads the file from there. The bundle need not to change between environments.
Then you write 2 bundles to provide the same package org.niyasc.jks, one with production file and one with test file.
Production env:
RestConsumerBundle + ProductionJksProviderBundle
Test env:
RestConsumerBundle + TestJksProviderBundle
Mind that deploying both of them may be possible and RestConsumerBundle will be bound to the first deployed bundle. You can eventually play with OSGi directives to give priority to one of them.
EDIT:
A more elegant solution would be creating an OSGi service which exposes the .jks as an InputStream or byte[]. You can even play with JNDI if you feel to.
From Blueprint declare the dependency as mandatory, so your bundle will not start if the service is not available.
<!-- RestConsumerBundle -->
<reference id="jksProvider"
interface="org.niyasc.jks.Provider"
availability="mandatory"/>
Storing the JKS files in the Fuse profile could be a good idea.
If you have a broker profile created, such as "mq-broker-Group.BrokerName", take a look at it via the Fuse Web Console.
You can then access the jks file as a resource in the property file, as in "truststore.file=profile:truststore.jks"
And also check the "Customizing the SSL keystore.jks and truststore.jks file" section of this chapter:
https://access.redhat.com/documentation/en-us/red_hat_jboss_fuse/6.3/html/fabric_guide/mq#MQ-BrokerConfig
It has some good pointers.
Regarding how to add files to a Fabric profile, you can store any resources under src/main/fabric8 and use the fabric8 Maven plugin. For more, see:
https://fabric8.io/gitbook/mavenPlugin.html
-Codrin

Access Sitecore DB from API in Console application

I would like to accesss the sitecore DB and items from console application like
Sitecore.Data.Database db = Sitecore.Context.Database
or
Sitecore.Data.Database db = Sitecore.Data.Database.GetDatabase("master")
how do I configure and setup my console application to access the DB as above?
Thanks Everyone for the suggestion, I am really interested in config changes, I used webservice, but it has very limited methods. For example, if I would like create an Item with the template and insert the item with prepopulated value, there is no such option. The reason I am looking for the console apporach is I would like to import the contents from XML or excel sheet and push those to the sitecore tree, eventually use the scheduled task to run the console app periodically. I do not want to copy the entire web.config and app_config. If anyone has already done this, could you please post your steps and necessary config changes?
You have two options I think:
1) Import the Sitecore bits of a website's web.config into your console application's app.config, so that the Sitecore API "just works"
I'm sure I read a blog post about this, but I can't find the reference right now. (I will have another look) But I think the simple but long winded approach is to copy all of the <sitecore/> element and all the separate files it references. I'm fairly sure you can whittle this down to a subset of the config required for data access with a bit of thinking.
2) Don't use the Sitecore API directly, connect to a web service that exposes access to it remotely.
There are a few of these that already exist. Sitecore itself exposes one, Sitecore Rocks has one, and Hedgehog TDS has one too. And you can always write your own (since any web service running inside the Sitecore ASP.Net app can make database calls and report values back and forth - just remember to consider security if this web service might end up exposed externally for any reason)
John West links to some relevant stuff here:
http://www.sitecore.net/Learn/Blogs/Technical-Blogs/John-West-Sitecore-Blog/Posts/2013/09/Getting-Data-Out-of-the-Sitecore-ASPNET-CMS.aspx
-- Edited to add --
I've not found the blog post I remember. But I came across this SO thread:
Accessing Sitecore API from a CLI tool
which refers to this blog post:
http://www.experimentsincode.com/?p=232
which I think gives the info you'll need for option 1.
(And it reminds me that, of course, when you copy the config stuff you have to copy the Sitecore binaries into your app's folder as well)
I would just like to expand on #JermDavis' post and note that Sitecore isn't a big fan of being accessed when not in a web application. However, if you still want to do this, you will need to make sure that you have all of the necessary configuration settings from the web.config and App_Config of your site in your console application's app.config file.
Moreover, you will never be able to call Sitecore.Context in a console application, as the Sitecore Context sits on top of the HttpContext which means that it must be an application and have a valid request for you to use it. What you are looking for is something more along the lines of Sitecore.Configuration.Factory.GetDatabase("master").
Good luck and happy coding :)
This sounds like a job for the Sitecore Item Web API. I use the Sitecore Item Web API whenever I need to access Sitecore data from the master database outside the context of the Content Management server or outside of the context of the Sitecore application. The Web API definitely does not allow you to do everything that the standard Sitecore API does but it can act as a good base and I now extend upon the Web API instead of writing my own custom web services whenever possible.
Thanks to JemDavis's advise.
After I copied the configuration and made changes to config section to get rid of conflicts. I copied almost all of Sitrecore, analytics and lucene dlls, it worked great.
Only thing you have to remember is, copy the app_config folder to the same location where your dlls are.
Thanks again JemDavis....

How do you debug CXF endpoint publishing?

Given the "cxf-osgi" example from fuse source's apache-servicemix-4.4.1-fuse-00-08, built with maven 3.0.3, when deploying it to apache karaf 2.2.4 and CXF 2.4.3 the web service is never published and never visible to the CXF servlet (http://localhost:8181/cxf/). There are no errors in the karaf log. How would one go about debugging such behavior?
It's worth turning up the log level(s) - you can do this permanently in the etc/org.ops4j.pax.logging.cfg or in the console with log:set TRACE org.apache.cxf - IIRC this will show some useful information.
Also check that it's actually published on localhost/127.0.0.1 - it may well be being published on another interface, the IP of the local network but not localhost. Try using 0.0.0.0 as the the address, that way it will bind to all available interfaces.
As you're using maven, you can download the CXF source (easily in Eclipse) and connect a remote debugger to the Karaf instance, with some strategically placed breakpoints you should be able to get a handle on what's going on.
Try changing to Equinox instead of the default of Felix. There is a bug in 2.4.3 in that it doesn't work well with Felix. Alternatively, CXF 2.4.4 is now available that should also fix it.
Take a look at this issue I filed this week: https://issues.apache.org/jira/browse/CXF-4058
What I found is that if my beans.xml is loaded before the cxf bundle jar, then the endpoints are registered with CXF but not with the OSGi http service. So everything looks good from the logs but the endpoints are never accessible. This is a race condition.
I did two workarounds: 1) in the short term, just move my own jars later in the boot order (I use Karaf features) so Spring and CXF are fully loaded before my beans.xml is read and 2) abandon Spring and roll my own binding code based loosely on this approach: http://eclipsesource.com/blogs/2012/01/23/an-osgi-jax-rs-connector-part-1-publishing-rest-services/
I just implemented solution #2 yesterday and I'm already extremely happy with it. It's solved all of my classloader issues (before I had to manually add a lot of Import-Package lines because BND doesn't see beans.xml references) and fixed my boot race condition.

First Hibernate project where to place addAnnotatedClass()

Hello all
I'm trying to build up my first Hibernate project for a Web app, but i'm having some issues
Trying to find out where to place the method:
AnnotationConfiguration config =
new AnnotationConfiguration();
config.addAnnotatedClass(Object.class);
config.configure();
i have some java beans decorated with annotations, shel i just insert it in the same class there the bean is?
Thank you
Ideally, you'd call this only if you are developing a standalone application. In a Java EE environment, you'd just define a persistence.xml file (or hibernate.cfg.xml) in your deployment archive and the container (like JBoss AS) would make a #PersistenceContext (EntityManager) available to you.
In a standalone application, you'd call this in your "Bootstrap" code. The one which sets up the environment.
In "non-Java EE" web applications (seriously, who still uses that?), you'd have to resort to some "hacks", like doing some initialization during context startup (so that you won't need to run this for all requests, as it's an expensive operation).
Partenon is right, you should bootstrap JPA with a persistence.xml.
The Stripes web framework it self does not offer any persistence services. But to make life easier there is an Stripersist extension that offers an out of the box session in view pattern (starts a transaction before the actionbean and does a roll back after the request is handled). Very good examples of how to use and configure Stripersist can be found in the book: Stripes: ...and Java web development is fun again

Resources