Can I avoid typing feature:repo-add camel 2.17.3 and have the features.xml file make this happen automatically? - apache-karaf

In Apache Karaf, before I install my features.xml file I need to type.
feature:repo-add camel 2.17.3
Is there any way to express in the features.xml file some command which makes this occur ? So that I can avoid typing it on the command line inside Karaf.
The motivation for this question is that it is nice that generally when I add a features.xml file to the deploy directory of Karaf that it can pull down all the dependent bundles by itself automatically. I like the fact that it has this automatic feature and the only thing I need to send is the features.xml. So this leads to my desire to encapsulate all the work in the features.xml file so that I do not need to type anything into the Karaf console.

This works. You need to refer to the camel feature xml using the repository tag.
See the cxf-dosgi samples feature xml.
The repository xml tag must appear within the features XML tag. So its like:
<?xml version="1.0" encoding="UTF-8"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" name="jump_micro">
<repository>mvn:org.apache.camel.karaf/apache-camel/2.17.3/xml/features</repository>
<feature description="jump_micro" version="1.0.0" name="jump_micro">
...

This is a shortcut for feature:repo-add mvn:org.apache.camel.karaf/apache-camel/2.17.3/xml/features
so no, this can't really be skipped as you somehow need to tell which feature file to use. If you skip the version it'll be that latest available version.

Related

How do I deploy application classes and Spring config files to Tomcat as a single jar?

Currently I create a new war file for each change but the changes are taking place in only a few classes and the Spring applicationContext.xml.
I would like to just update a jar file that contains these classes and not continually re-deploy hundreds of files that have not changed. I can create the jar easily enough but where do I put it and do I have to tell Spring to look in a specific jar for its' config files?
It is quite impossible to hot-redeploy code in Tomcat without using extra tools like JRebel or custom JVM agents.
But it is possible to modularize you application by:
1: Putting JARs to $TOMCAT_HOME/lib. Never do this, this solution is good only for simple cases.
2: Tune context.xml, putting Loader in it, like below:
<Context antiJARLocking="true" path="/">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="${catalina.base}/my-app-plugins/*.jar"/>
</Context>
This will enable you putting JAR file in $TOMCAT_HOME/my-app-plugins and thet will be added to the classpath of you app. You should put context.xml to the src/main/webapp/META-INF folder (Maven layout). However, restart is still needed.
3: Use OSGi. May be an overkill.

Specify different path for provider iisApp when creating package with msdeploy

How I make the package
I make the msdeploy package like this:
msdeploy.exe -verb:sync -source:iisApp=c:\content\ -dest:package=c:\pkg.zip
The c:\content directory has a single index.html file.
Result
The output looks like this:
Info: Adding package (package).
Info: Adding child iisApp (c:\content\).
Info: Adding child createApp (c:\content\).
Info: Adding child contentPath (c:\content\).
Info: Adding child dirPath (c:\content\).
Info: Adding child filePath (c:\content\index.html).
Total changes: 6 (6 added, 0 deleted, 0 updated, 0 parameters changed, 0 bytes copied)
If I extract the content of c:\pkg.zip into directory c:\pkg it looks like this:
archive.xml
systemInfo.xml
Content\c_C
Content\c_C\content
Content\c_C\content\index.html
If I dump the package like this:
msdeploy.exe -verb:dump -source:package=c:\pkg.zip -xml
I get:
<output>
<MSDeploy.iisApp>
<iisApp path="c:\content\">
<createApp
path="c:\content\"
isDest="False"
managedRuntimeVersion=""
enable32BitAppOnWin64=""
managedPipelineMode=""
applicationPool=""
appExists="True" />
<contentPath path="c:\content\">
<dirPath
path="c:\content\"
securityDescriptor="D:"
parentSecurityDescriptors=""
attributes="Directory">
<filePath
path="index.html"
size="0"
attributes="Archive"
lastWriteTime="07/07/2011 20:58:00"
securityDescriptor="D:" />
</dirPath>
</contentPath>
</iisApp>
</MSDeploy.iisApp>
</output>
How I want it to be
I don't want the package to depend upon the current location of the site files. I'm going to send the package to a customer, and I don't want any detailes about the packaging process to get shipped with the package. I want the content of the package c:\pkg.zip to be like this:
archive.xml
systemInfo.xml
Content\index.html
I want the package to be able to create an IIS application, so I need a virtual path. I also want to install the package into the default location. So the physical path also has to change. I want the dump to look something like this:
<output>
<MSDeploy.iisApp>
<iisApp path="Default Web Site\Site">
<createApp
path="Default Web Site\Site"
isDest="False"
managedRuntimeVersion=""
enable32BitAppOnWin64=""
managedPipelineMode=""
applicationPool=""
appExists="False" />
<contentPath path="c:\inetpub\wwwroot\site">
<dirPath
path="c:\inetpub\wwwroot\site"
securityDescriptor="D:"
parentSecurityDescriptors=""
attributes="Directory">
<filePath
path="index.html"
size="0"
attributes="Archive"
lastWriteTime="07/07/2011 20:58:00"
securityDescriptor="D:" />
</dirPath>
</contentPath>
</iisApp>
</MSDeploy.iisApp>
</output>
I have changed the iisApp and createApp provider path attributes to be Default Web Site\Site. And I changed the contentPath and dirPath provider path attributes to be c:\inetpub\wwwroot\site.
Questions
How can I accomplish this?
You need to look at MS Deploy replace rules, a useful feature well hidden on the MS Deploy Team Blog.
In your case, you will need to extend your command line with a pile of replace expressions, something like this:
msdeploy.exe
-verb:sync
-source:iisApp=c:\content\
-dest:package=c:\pkg.zip
-replace:objectName=iisApp,targetAttributeName=path,
replace="Default Website\Site"
-replace:objectName=createApp,targetAttributeName=path,
replace="Default Website\Site"
-replace:objectName=contentPath,targetAttributeName=path,
replace="c:\inetpub\wwwroot\site"
-replace:objectName=dirPath,targetAttributeName=path,match="^c:\content",
replace="c:\inetpub\wwwroot\site"
Running this should produce your desired output.
In the above sample, the first 3 replace rules match by tag name (objectName) and attribute name (targetAttributeName), and overwrites with the specified replace string.
The last replace rule will match all path attributes of all dirPath tags beginning with "c:\content" and will replace only that part of the attribute value with the replace string.
Finally, I haven't found a way to avoid having the package zip-file contain the original source folder names. The only workaround would be to package from a neutral, temporary location like "c:\site".
So the procedure is:
Copy your stuff to a neutral, temporary location.
Create your package from here.
Use the verb:dump to see the generated xml.
Create your package again with added replace rules for everything you want changed in the package.
Take a headache pill ;-)
I had more or less the same problems.
First things first:
The long deployment-machine-specific paths
To that effect, I used a trick found at http://sedodream.com/2013/01/13/WebPackagingFixingTheLongPathIssue.aspx
As suggested in the post, one can modify the desired (you can have several) .pubxml file under the Properties/PublishProfiles folder in your project. This is the approach I followed since it allowed me to customize the behavior per publishing profile.
If I'm not mistaken though, I believe you can apply the same modification to the {project-name}.wpp.targets file (which probably doesn't exists yet) on the project root directory. Changes here though, affect the web publishing pipeline (wpp) and thus all publishing profiles found in the project.
However...
This approach is just about to spoil your deployment when it comes time to replace your connection strings with those provided by your publishing profile. The reason: the above trick doesn't affect connection strings since they are being created automatically by the wpp at build time. Buh-huh!
The solution I found for that problem was twofold:
1.) Created a parameters.xml file where I manually declared the connection strings. Ok, maybe I copied them from the parameters.xml file within my package's .zip file since I was deploying to a package. That helped.
They look somegthing like this:
<parameter name="myConnection-Web.config Connection String" defaultValue="" tags="SqlConnectionString"
description="myConnection Connection String used in web.config by the application to access the database.">
<parameterEntry kind="XmlFile" scope="DeploymentPackage\\Web\.config$" match="/configuration/connectionStrings/add[#name='myConnection']/#connectionString" />
</parameter>
2.) Included the following line at the top of the same .pubxml file we modified earlier
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
And... VoilĂ !
Create ISS App
With the above approach hopefully you declared several parameters, including the connection strings.
When you create a package, however, regardless of wheter you created a parameters.xml or not, a *.SetParameters.xml template file is created for you. Within it you will see as the very first parameter the "IIS Web Application Name", which will default to whatever you inserted in your publishing profile. You can change that; to whatever you want.
Remember I said template before? I meant it; it's just a template. You're suppose to take that *.SetParameters.xml file and make as many copies of it as needed. What are they for? Environment related parameters. You could have a:
DEV.SetParameters.xml
QA.SetParameters.xml
Staging.SetParameters.xml
Production.SetParameters.xml
... and so on and so forth
and then use the parameters file best suited for the job (or the environment) like so:
{yourProjectName}.deploy.cmd /Y /M:{targetServer} [...] -setParamFile:QA.SetParameters.xml
or its equivalent MsDeploy command line of course.
Now, by default, the manifest created for you at build time, and stashed within your package under the archive.xml file, will use an iisApp provider first and foremost. This is good, cause this provider, unlike the createApp provider, will actually create the directory for you if it doesn't exist. At least according to this note from TechNet:
"Unlike the iisApp provider, if the physical folder for the new application does not exist, the createApp provider does not create a physical folder underneath the folder of the parent site; it only creates a reference in configuration to such a folder. If you want a physical folder created, you will have to create it manually before or after using createApp. For this reason, you should normally use the iisApp provider instead. The iisApp provider is the more appropriate choice because it uses the createApp provider as an initial step in a series of steps that include the creation of the application in configuration, the creation of a physical folder for the application if the folder does not exist, and the copying of content files into the folder of the new application."
I would be happy to include the links... but since I don't have 10+ points I'm allowed only one per post. Go figure! :)
So, in short...
... by the work done on the first part, you probably won't need to do much in order to have the folder created at deploy time in the target server.
In case you do need to override that though, you can either define your own manifest file and deploy off of it (a separate topic)... or you can follow #peter_raven advice and override its value using the -Replace rules from MsDeploy.
Either one would work as a charm.
The package prefix is removed by supplying the kind, scope, and match properties as shown below:
"msdeploy.exe" \
-verb:sync \
-source:iisApp="[Path to your website contents]" \
-declareParam:name="IIS Web Application Name",kind="ProviderPath",scope="IisApp",match="^C:\\path\\to\\your\\site\\folder",defaultValue="Default Web Site/SomeSite" \
-dest:package=[WebDeployPackageName].zip
I've managed to resolve a problem with manually defined connection strings while using the solution from #SkyFighter. Now one can use the auto-parameterization feature and have the connection string parameters with correct scopes.
Fortunately there is a place inside WPP to inject into. Unfortunately I had to use AfterTarget/BeforeTarget rather than SomeTargetDependsOn variables to narrow down the new target's placement.
And here is the target itself:
<Target Name="Replace_WebConfigsToAutoParmeterizeCS_TransformScope"
AfterTargets="PreAutoParameterizationWebConfigConnectionStrings"
BeforeTargets="AutoParameterizationWebConfigConnectionStringsCore"
Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' ">
<ItemGroup>
<_WebConfigsToAutoParmeterizeCS>
<TransformScope>$([System.String]::Copy('%(TransformScope)').Replace('$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))', '$(PackagePath)'))</TransformScope>
</_WebConfigsToAutoParmeterizeCS>
</ItemGroup>
</Target>
It is driven by the same variables as in the Sayed's sample for fixing long paths. So place this target anywhere those variables already available.
P.S. This trick/hack requires at least MSBuild v3.5 where metadata manipulation was first introduced.

Cleanest Jetty Configuration for Development?

EDIT: I think I should clarify my intent...
I'm trying to simplify the development iteration cycle of write-code >> build WAR >> deploy >> refresh >> repeat. I'd like to be relatively independent of IDE (i.e., I don't want Eclipse or IntelliJ plug-ins doing the work). I want to be able to edit code/static files and build as needed into my WAR source directory, and just have run/debug setup as a command line call to a centralized Jetty installation.
Later I'd like to be able to perform the actual deployment using generally the same setup but with a packaged up WAR. I don't want to have my app code specific to my IDE or Jetty.
So perhaps a better way to ask this question is What have you found is the cleanest way to use Jetty as your dev/debug app server?
Say I want to have a minimal Jetty 7 installation. I want as minimal of XML configuration as possible, I just need the raw Servlet API, no JSP, no filtering, etc. I just want to be able to have some custom servlets and have static files served up if they exist. This will be the only WAR and it will sit as the root for a given port.
Ideally, for ease of deployment I'd like to have the Jetty directory just be the standard download, and my WAR / XML config be separate from these standard Jetty files. In my invocation of Jetty I'd like to pass in this minimal XML and go.
I'm finding that the documentation is all over the place and much of it is for Jetty 6 or specific to various other packages (Spring, etc.). I figure if I have this minimal configuration down then adding additional abstractions on top will be a lot cleaner. Also it will allow me to more cleanly deal with embedded-Jetty scenarios.
This SO question is an example scenario where this XML would be useful Jetty Run War Using only command line
What would be the minimal XML needed for specifying this one WAR location and the hosts/port to serve it?
Thanks in advance for any snippets or links.
Jetty has migrated to Eclipse. There is very subtle info on this. This also led in change in package name, which is another level of nuance. They did publish a util to convert Jetty6 setting to Jetty 7 setting, but again -- not very popular. I am dissapointed from Eclipse Jetty forum. Here is where you should look for documentation on Jetty 7 onwards http://wiki.eclipse.org/Jetty/Starting
I think this is the minimal jetty.xml taken from http://wiki.eclipse.org/Jetty/Reference/jetty.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">\
<Configure id="Server" class="org.eclipse.jetty.server.Server">
</Configure>
But, I would rather like to start from a copy of $JETTY_HOME/etc/jetty.xml and would modify from there.
If you are Okay with $JETTY_HOME/webapps directory, you can set up the port by modifying this part
<Configure id="Server" class="org.eclipse.jetty.server.Server">
...
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.port" default="7777"/></Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
....
</Configure>
Else, I will modify context.xml the way explained here (for Jetty 7) How to serve webbapp A from portA and webapp B from portB
Also refer these pages:
http://wiki.eclipse.org/Jetty/Reference/jetty.xml
http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax
http://communitymapbuilder.org/display/JETTY/JNDI
....
Edit#1: sorry for wrong URL for webapp per connector. I have updated the link to How to serve webbapp A from portA and webapp B from portB to point to the doc that is meant for Jetty 7.
Update on 'how you deal with Jetty on various environments?'
Dev
We use Maven, so embeded Jetty works for us. We just run mvn clean install run:jetty and the port is configured in Maven's config file, namely pom.xml. This is not IDE dependent plus Jetty can easily be embedded using ANT, but I never tried.
Test
We have stand-alone Jetty running. I've configured port and tuned parameters, removed default apps (e.g. root.war etc) and created a context.xml with app specific ports and deployment directory. (Unfortunately, I have asked this question on Eclipse Jetty's mailing list and no one bothered to answer). This is one time setting.
For test builds/deployments, we have a build script that builds the WAR as per test env specs and then uploads it to test environment. After, that we invoke a shell script that (1)stops Jetty, (2) copies war file to myApp's webapp direactory and (3) restarts Jetty.
However, easier way to do this is by using Maven's Cargo plugin. The bad luck was that I was using Jetty 7.1.6 which was incompatible with Cargo. Later they fixed it, but I had got my job done by custom script.
Prod
Prod has almost same procedure as test, except. The tunings are done for higher security and load-balancing. But from deployment POV, there is nothing different from Test case to Prod.
Notice that I have not bothered about what XML files are and how many must be there. I have just used the ones that are my concerns -- jetty.xml and context.xml. Plus, I found it's much cleaner to use jetty.conf and jetty.sh for passing JVM params, custom XMLs and for starting and stopping.
Hope this helps.
On hot deployment:
Now, if you use Maven and use embedded Jetty. It just knows when the code is changed -- like "gunshot sniffer". In dev envt, you run Jetty, make changes, refresh page, and see your changes -- hot deployment. Find more here http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin look for scanIntervalSeconds
This doesn't fully answer your question, but in case it helps, here's some pretty minimal code using embedded Jetty 7 to fire up a server with one root servlet:
HandlerCollection handlers = new HandlerCollection();
ServletContextHandler root = new ServletContextHandler(handlers, "/", ServletContextHandler.NO_SESSIONS|ServletContextHandler.NO_SECURITY);
root.addServlet(new ServletHolder(new MyServlet()), "/*");
Server server = new Server(8080);
server.setHandler(handlers);
server.start();
See of course http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty.
If you are building with maven (which is IDE independent) then you should debug with the maven jetty plugin. Basically you run the app as "mvn jetty:run" on the commandline it all just works without having to do any redeployment. Most good IDEs how have maven support built in and lets you run/debug the app as a maven; meaning that maven is run which starts the jetty plugin which starts the app and you can debug it. Since everything is running out of the IDE source and bin folders you don't even need a jetty server install.
Here is a demo project which runs that way https://github.com/simbo1905/ZkToDo2/blob/master/commandline.build.and.run.txt and here is how to run it under eclipse https://github.com/simbo1905/ZkToDo2/blob/master/eclipse.indigo.build.and.debug.txt but any IDE which understands maven should work. Take a look at the pom.xml where it sets up the maven jetty plugin.
I would use Gradle and scan the build output folder every few seconds for changes in the build.
In a build.gradle file:
apply plugin: 'jetty'
...
jettyRun.doFirst {
// set system properties, etc here for bootstrapping
}
jettyRun {
httpPort = 8989
reload = 'automatic'
scanIntervalSeconds = 3
daemon = false
}
That's it. You can choose to have the IDE auto-build for you, and point at that directory. But you can also choose not to. This solution is not tied at all to an IDE.
I thought I'd update with what I now do. I've written a tiny command line app / Maven archetype which works like how I thought this all should have in the first place. The bootstrap app lets you launch your servlet container of choice (Jetty, Tomcat, GlassFish) by just passing it the path to the WAR and your port.
Using Maven, you can create and package your own instance of this simple app:
mvn archetype:generate \
-DarchetypeGroupId=org.duelengine \
-DarchetypeArtifactId=war-bootstrap-archetype \
-DarchetypeVersion=0.2.1
Then you launch it like this:
java -jar bootstrap.jar -war myapp.war -p 8080 --jetty
Here's the source for the utility and the archetype: https://bitbucket.org/mckamey/war-bootstrap

How does one create Channels at runtime using BlazeDS?

So as you may or may not know, BlazeDS (open source version of LiveCycle Data Services) is a nice way to get your server-side Java and client-side Flex application to play together. Unfortunately, it does have several pitfalls that need to be corrected. I'll try to explain one of them here.
All of BlazeDS's configuration is written via XML files in the flex/ folder of your webapp. The default names are separated for clarity, such as services-config.xml, remoting-config.xml, messaging-config.xml, etc. In these configuration files (particularly services-config.xml), Channels are defined; these setup URIs and objects used to capture and send information between the server and the client. In these config files, it is quite common to use a syntax like so:
<channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
<endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
<properties>
<add-no-cache-headers>false</add-no-cache-headers>
</properties>
</channel-definition>
Unfortunately, what they don't tell you is that some of these key-in replacements (ie: {context.root}) are not replaced dynamically upon execution but upon compilation of the WAR file you intend to distribute. Obviously not a good idea when switching domains.
So, instead I seek to dynamically define these channels. According to the documentation, that's all good and fine, but it only works if the channel already exists when the webapp is launched. I feel like that sort of defeats the point.
So my question is, how do you truly create channels dynamically so that both the client and the server recognize their existence?
Read this blog post; I believe it is what you're after.
I believe these xml config files have no direct relation to the server at all. They are used to tell the SWF how to find the server.
During Compile time of your Flex App; the services-config information is, in essence, hard coded into the SWF.

How do I test that all my expected web.config settings have been defined?

I am using the built in test framework in VS2008 and I would like be able to write a test that makes sure all the expected web.config settings have been defined so that if by accident one is removed or changed my suite of tests will detect it and not have to be tested in a runtime scenario. How would I set this up?
I do not want to setup a mockup of my web.config since I don't want to maintain two versions and this would make my test invalid anyways since I am really trying to capture the fact that the project's web.config is correct.
Any suggestions, alternatives, hints?
Solution: I ended up using the copy in the pre-build that was suggested with one change. On copy I rename the web.config to app.config so that the test project would automatically pick it up.
I tried to split out the config files as suggested as well but the problem I ran into was when the test project ran, it actually didn't run out of the bin directory (which setting the config files to 'Content' type would copy to) but instead to a results directory that has been pre defined. I could not figure out how to make it copy thos extra files to this results directory so the config files could never be found.
I'am using the pre-build event to copy working web.config to your test project directory.
Set the command line of the pre-build event of test project to string like this:
copy $(SolutionDir)\YourWebAppDir\web.config $(ProjectDir) /y
After that your tests will always run with actual web.config version.
Comment to pcampbell's answer:
I think if you use the configSource attribute you can just set it to the same path in web.config of your web app and app.config of test project and that makes not necessary to use build events.
sorry, I can't leave comments yet.
To expand on bniwredyc's answer, perhaps consider:
refactoring your web.config to reference a new config file like appSettings.config or similar.
modify your project's web.config to:
<appSettings configSource="appSettings.config" />
modify your Unit Test project's app.config to use this file as well.
modify your post or pre-build events to copy just this file.
this also helps ease of deployment in Test/Staging/Prod
Ultimately, the web.config is an XML file. You could generate a schema to validate the sections required are present and that required values have been populated. Obviously, you couldn't contextually validate any sort of business logic that the configuration might contain, but you could use a combination of an XSD validation plus a lightweight class that is used to parse conditions within the file.
Used in conjunction with a copy pre-build event you actually create a very nice test harness for your production quality configurations.

Resources