How to deploy configfile before bundles - apache-karaf

Given a feature with a <configfile> and a <bundle>, how can I ensure that the file is deployed before the bundle? What I'm seeing is that my bundle gets started first and the file deployed second (even if <configfile> is the first tag).
I guess this is could be the <bundle> being considered a pre-requisite so it makes sense to start that before processing the rest of the <feature>?

Actually if you are doing it right, your bundles shouldn't care if the configuration is available or not. The service should either not be started or with a default setting in case no "external" configuration has been set. In case of a new configuration the service will be restarted with the new configuration.

Related

Editing configuration files in Pax Exam

I am using Pax Exam to perform integration tests to my OSGi application. I have a configuration factory in which I specify the Karaf feature of my application to be installed in the test container and then modify some of a proerty of a .cfg file installed as part of my feature.
public class TestConfigurationFactory implements ConfigurationFactory {
#Override
public Option[] createConfiguration() {
return options(
karafDistributionConfiguration()
.frameworkUrl(
maven().groupId("org.apache.karaf")
.artifactId("apache-karaf")
.version("3.0.1").type("tar.gz"))
.unpackDirectory(new File("target/exam"))
.useDeployFolder(false),
keepRuntimeFolder(),
// Karaf (own) features.
KarafDistributionOption.features(
maven().groupId("org.apache.karaf.features")
.artifactId("standard").classifier("features")
.version("3.0.1").type("xml"), "scr"),
// CXF features.
KarafDistributionOption.features(maven()
.groupId("org.apache.cxf.karaf")
.artifactId("apache-cxf").version("2.7.9")
.classifier("features").type("xml")),
// Application features.
KarafDistributionOption.features(
maven().groupId("com.me.project")
.artifactId("my-karaf-features")
.version("1.0.0-SNAPSHOT")
.classifier("features").type("xml"), "my-feature"),
KarafDistributionOption.editConfigurationFilePut(
"etc/com.me.test.cfg", "key", "value"));
}
}
The property I specify in editConfigurationFilePut is modified correctly, however the rest of the .cfg file's properties are deleted. If I use the editConfigurationFilePut method to edit one of Karaf's configuration files it works as expected (just adds the new property without modifying the existing ones) so I am thinking that perhaps the problem is that Pax Exam attempts to modify the configuration before the .cfg file is installed by my feature and therefore creates a new file to put the property in. If this is the case is there some way to synchronise this process so that the .cfg file is edited only after the feature is properly installed?
There are a two different reasons for this.
1) The feature does get installed after the configfile has been "edited"
2) The feature only contains a config section and not a configfile section
I'd guess reason one is the most likely cause of this since it needs a running Karaf to install a feature through Pax Exam. So to work around reason one, replace the config with a config file present in your test project.
For reason two, make sure the feature actually does reference a config instead of a configuration admin config, or add your config to the configuration of the config-admin service. You can achieve this by injecting the ConfigAdmin service in your unit test and add your properties to the configuration pid.
EDIT:
Combine both solutions
Since because of 1) it takes longer for the config-file to be actually available, let config-admin service do the rest.
Make sure your test does retrieve the config-admin service either by injecting it or by waiting for it's availability.
Now within a #Before method make sure you wait till your config is complete and change it from there on. This way you don't need to duplicate the config files.

Deploying AD FS web application to multiple environments

Background:
I have an ASP.NET web app configured for federation with AD FS. I'm using VS 2012, and have TFS for source control, builds and deployments.
We're currently deploying by copying the built files from the build server (TFS) to the alpha environment. From there we would copy from alpha to beta, then from beta to production. So there is not a unique build for each environment. The way we're handling environment-specific settings right now is there is one config file that has all the settings for each environment Let's call this EnvironmentSpecificSettings.config (I'll refer to it below). There is a static file on each server that indicates which environment the server should be in, and so when that config file is read in, the matching settings can be applied.
The problem:
The ADFS configuration is handled in the web.config. There are a few things that are specific to the environment. How might I handle this within my current deployment paradigm? I had a couple of ideas:
include a file reference in the web.config that reads in a static environment-specific file that would not be part of the deployment.
Try to pull something off in Application_Start that would read in settings from EnvironmentSpecificSettings.config (mentioned above) and alter the web.config.
Try to tweak the configuration of the WSFederationAuthenticationModule at runtime
the first idea (#1) is less than optimal because it requires files hanging around outside of source control and outside of deployments, however it should work easily enough. Next, #2 I kinda think isn't possible. I'm not sure you can change your web.config like I am hoping, but maybe? Finally, #3 Is only reasonable because I'm in a special situation where I'm not doing regular passive authentication, instead I'm manually redirecting to adfs, so I have a chance to change settings, such as injecting the whr parameter to avoid HRD. So, it might be possible, however, I'm not sure how or if you can change some of these values on the fly such as thumbprint, or wsFederation issuer or realm.
Does anyone have any better ideas or experience in handling environment-specific settings without doing the visual studio web deploys with transforms?

Apache Karaf - bundle starts but does nothing?

I'm new to Karaf. I have a jar that has a class App with a method main. When I drop the jar in the The Karaf log service console says the bundle is started but nothing seems to happen. The first thing (the jar) does is a simple database write so I can see if it's running (no log file is generated although one is expected).
The jar depends on lots of other jars. Our sysadmin will not install Maven on the production servers. Where does one put helper jars (like mysql-connector-java-[version].jar)?
Does Karaf use the Manifest file to find the main class? Do I have to implement some special interface or something?
thanks for any help.
As Karaf is a OSGi Container, you should first read some stuff on how to write proper OSGi bundles.
First of all you'll need a Activator that'll start your bundle (just like a main). A Main Class is never interpreted. Yes Karaf, as it is a OSGi container, does "read" the Manifest, but to make sure first it's a proper OSGi bundle second how the resolving should take place by reading Package-Import/-Export.
Regarding the "Packaging" - using lot's of other jar's/bunldes - , you'd either can built a custom Karaf (read the Karaf documentation on how to do this) or create a KAR for your Bundles containing your bundles and a feature.xml (again take a look at the documentation at Karaf)

how to deploy flex app using different web service urls?

Is there some sort of configuration settings in FlashBuilder 4.5 where you can easily switch between webservice urls? Right now I have to delete and recreate the web service every time I switch from local to production and vice versa.
The need/requirement is this – Since I work in a startup, we keep changing servers, and their IP addresses. And being a service oriented application – I need to be able to edit the webservice endpoints in my Flex application in a easy manner every time this happens.
My Solution for this -
Assumption is that my webservice endpoint looks like this -
http:////ListAllServices/
1) Create a file config.xml in a folder named “settings” that sits in the root folder of your Flex application – outside the “src” folder. And the config.xml will be a simple xml file of the following format -
localhostTestFlexApp
At the end of this exercise the directory structure of your flex source code will look like this -
flex_src(root of the source code)
-com(some source folder)
–testapp
—view
—
-images
-settings
–config.xml
-appName.mxml
2) Now in your application code, setup a HTTPService object either in mxml or action script. Set the url of that object to this value- “settings/config.xml” – And the above xml fiel containing the current settings will be loaded into memory .
Now you can store these values in a singleton object and construct your Webservice call at runtime.
And whenever you want to move this to a new server in production, edit the tag of your config.xml and you should be good to go.
And this can be automated as well via the EnvGen ant task.
This is not the best way but yes it is very helpful while switching among servers.
Alrighty... The way I was doing it before in fact worked. The problem was browser caching.
For the benefit of others I modified the subsclass for the generated service and replace the wsdl variable with whatever endpoint I need.

How to configure WCF in a separate dll project

I'm developing a web application (ASP.NET 3.5) that will consume a number of web services. I have created a separate dll-project for each web service: these projects contains the service reference and client code.
However, the calling website MUST have the <system.serviceModel> information (the <bindings> and <client> nodes) in it's web.config, even though this information is also in the dll's app.config file! I have tried copying the serviceclass.dll.config over to the bin directory of the website, but this didn't help.
Is there any way to centralize the configuration of a WCF client?
I've only limited WCF experience, all with BasicHTTP bindings. But I'm allergic to WCF's xml files and have managed to avoid them thus far. I don't recomend this generally but I put the configuration details in my apps existing configuration store and then apply them programatically. E.g. With a Web service proxy I use the constructor for the Client that takes 'bindings'and 'endpoint' and programatically apply the settings to the bindings & endpoint.
A more elegent solution appears to be descibed here: Reading WCF Configuration from a Custom Location, but I haven't tried it yet.
From my experience, library projects never read app.config.
So you can really delete the file because it is not used. The library's host configuration is read instead, so that is the only place the endpoint and binding configuration should be.
It's possible to forgo xml config and build up the Binding and Endpoint classes associated with the service in the constructor or a custom "Service Factory". iDesign has some good information on this:
http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=5&tabid=11
(See In Proc Factory)
In their approach, you set attributes on your services to specify at a high level how they should work (ie [Internet], [Intranet], [BusinessToBusiness]), and the service factory configures the service according to best practices for each scenario. Their book describes building this sort of service:
http://www.amazon.com/Programming-WCF-Services-Juval-Lowy/dp/0596526997
If you just want to share configuration XML config, maybe use the configSource attribute to specify a path for configuration: http://weblogs.asp.net/cibrax/archive/2007/07/24/configsource-attribute-on-system-servicemodel-section.aspx
Remember that a configuration file is is read by an executable that has an entry point. A library dll does not have an entry point so it is not the assembly that will read it. The executing assembly must have a configuration file to read.
If you would like to centralize your web configs then I would suggest you look into nesting them in IIS with virtual directories. This will allow you to use the configuration inheritance to centralize whatever you need.
There are 2 options.
Option 1. Working with channels.
If you are working with channels directly, .NET 4.0 and .NET 4.5 has the ConfigurationChannelFactory. The example on MSDN looks like this:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "Test.config";
Configuration newConfiguration = ConfigurationManager.OpenMappedExeConfiguration(
fileMap,
ConfigurationUserLevel.None);
ConfigurationChannelFactory<ICalculatorChannel> factory1 =
new ConfigurationChannelFactory<ICalculatorChannel>(
"endpoint1",
newConfiguration,
new EndpointAddress("http://localhost:8000/servicemodelsamples/service"));
ICalculatorChannel client1 = factory1.CreateChannel();
As pointed out by Langdon, you can use the endpoint address from the configuration file by simply passing in null, like this:
var factory1 = new ConfigurationChannelFactory<ICalculatorChannel>(
"endpoint1",
newConfiguration,
null);
ICalculatorChannel client1 = factory1.CreateChannel();
This is discussed in the MSDN documentation.
Option 2. Working with proxies.
If you're working with code-generated proxies, you can read the config file and load a ServiceModelSectionGroup. There is a bit more work involved than simply using the ConfigurationChannelFactory but at least you can continue using the generated proxy (that under the hood uses a ChannelFactory and manages the IChannelFactory for you.
Pablo Cibraro shows a nice example of this here: Getting WCF Bindings and Behaviors from any config source
First of all class libraries (DLLs) do not have their own configuration, however they can read the configuration of their host (Web/Executable etc.). That being said, I still maintain an app.config file on the library projects as a template and easy reference.
As far as the service configuration itself is concerned, WCF configuration can make somebody easily pull their hair out. It is an over-engineered over-complicated piece. The goal of your applications should be to depend least on the configuration, while maintaining flexibility of deployment scenarios your product is going to come across.

Resources