How to change value of existing variables in Cruise control config file - cruisecontrol.net

I have created a variable in cruise control configuration file
I want to change the value of this variable in cruise control later during execution. Basically what I want is while executing task1, value of 'MyVariable' should be say 'val1' and while executing task2, value should be say 'val2'.
One more thing that I want is, there should be no manual interaction or manual assignment from ui, the value should be changed automatically.
Can anybody please help me in achieving this? Any suggestion/ inputs would be great help. Thanks in advance.

I'm using the following approach to compile one MSBuild with different parameters (ccnet 1.8):
<cb:define name="Build">
<msbuild>
<some_parameter>$(MyVariable)</some_parameter>
<other_parameter>parameter_value</other_parameter>
</msbuild>
</cb:define>
and then in tasks section:
<cb:Build MyVariable="val1" />
<cb:Build MyVariable="val2" />

If those values of MyVariable are constant (I mean always the same for given task) then I'd use preprocessor. Then you can override the value with cb:scope.
For example, here's what I do with projects configuration:
<cb:scope
Project.Name = "ProjectName - Feedback - Integration tests"
Project.ShortName = "project-name-feedback-quick"
Project.Category = "Project Name - Feedback"
Project.Description = "Run integration tests"
>
<project name="$(Project.Name)" description="$(Project.Description)">
<artifactDirectory>$(CIRootFolderPath)\$(Project.ShortName)\Artifacts</artifactDirectory>
<workingDirectory>$(CIRootFolderPath)\$(Project.ShortName)\WorkingDir</workingDirectory>
<state type="state" directory="$(CIRootFolderPath)\$(Project.ShortName)" />
So you would surround each <task> with <cb:scope> block and redefine value of MyVariable in there.

Related

Mule 3 retrieving the placeholder value dynamically

I have a use-case that I need to retrieve the value from my properties file but that key should be derived dynamically from my query params.
How to handle this in MEL or Groovy? I am aware it is possible in DW.
Http request
https://localhost:9898/getStore?search=customer.weststore.name
And my placeholders are -
file.properties
customer.weststore.name=TESTING
customer.eaststore.name=IRERRER
So the way I need to access something like this
<set-variable variableName="westDetail" value="#[message.inboundProperites['customer.weststore.name']" doc:name="Variable"/>
<logger message="${westDetail}" level="INFO" /> --> Failed as no placeholder available
When I tried the above it's failing due to no placeholder as "westDetail" available whereas I need the fetch that particular key from the properties file.
This is something related to this article - https://help.mulesoft.com/s/question/0D52T00004mXTQUSA4/dynamically-read-property-values-from-a-properties-file-in-mule but the only solution provided with DW not MEL or Groovy.
How anyone advises, Is it possible?
I understand that the problem is that you want to query the properties by a key that is obtained at execution.
You are doing it incorrectly. ${} is for evaluating the value of a property, which is done at initialization time of the application. You missed that get the actual value in the set-variable.
#[] is for executing a MEL expression, which happens at execution time. flowVars.westDetail is a MEL expression that returns the value of flow variable westDetail. You can't use a MEL expression to evaluate the property placeholder ${}, because they are evaluated at different times.
A solution is to use a Spring bean to store the properties, instead of a configuration properties placeholder. Then you can assign it to a flow variable and access it like a map.
Example:
<spring:beans>
<spring:bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<spring:property name="location" value="classpath:items.properties"/>
</spring:bean>
</spring:beans>
<flow name="myFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-variable value="#[app.registry.myProperties]" variableName="props"></set-variable>
<logger message="a=#[flowVars.props['a']]" level="INFO"/>
</flow>
items.properties:
a=1
b=2
c=3
Output:
a=1

Is there a way to set the minlevel of a NLog logger via a variable?

Using NLog v4.4.12, I have this in my App.config
<nlog>
<include file="..\Common\Logs\Variables.xml" />
<rules>
<logger name="*" minlevel="${logLevel}" writeTo="LogFile, Wcf"/>
</rules>
</nlog>
And here is my Variables.xml file content
<?xml version="1.0" encoding="utf-8"?>
<nlog autoReload="true">
<variable name="logLevel" value="Fatal" />
</nlog>
But I get an Exception when launching my app
Unknown log level: ${logLevel}
Am I doing something wrong or is it just impossible?
The goal of this is to eventually have an xml file per project that need to log things so each project can have his own minlevel and be able to change it at runtime via the edition of this xml.
Edit: Adding this code just before the Exception is thrown shows that my variable is there with the desired value.
var nl = NLog.LogManager.Configuration;
if (nl != null)
{
if (nl.Variables.ContainsKey("logLevel"))
{
Console.WriteLine(nl.Variables["logLevel"]);
}
}
** Updated Answer **
NLog ver. 4.6 added support for using NLog-Config-Variables in minLevel. See https://github.com/NLog/NLog/pull/2709
NLog ver. 4.6.7 added support for adjusting minLevel at runtime, by modifying NLog-Config-Variables and calling ReconfigExistingLoggers(). See https://github.com/NLog/NLog/pull/3184
** Original Answer **
Unfortunately you can't use layout renderers (the ${...}) in the <logger> attributes like minLevel, level, etc
There are two options:
Use filters
<logger name="*" writeTo="LogFile, Wcf">
<filters>
<when condition="(level < ${logLevel})" action="Ignore"/>
</filters>
</logger>
Downsides:
less readable
hurt performance more compared to the minLevel attribute
Change the rules in code
var rule = config.LoggingRules[0];
// disable old levels, enable new
rule.DisableLoggingForLevel(LogLevel.Debug);
rule.DisableLoggingForLevel(LogLevel.Trace);
rule.EnableLoggingForLevels(LogLevel.Info, LogLevel.Fatal);
//apply config
LogManager.Configuration = config;
I had my variables in a config file as part of a Service Fabric application, which would vary by environment, and wanted these to override the values in my Nlog.config file.
As per the user above, I came up against the same problem with loglevel when I wished to set a minimum level for it. Rather than hardcoding the levels in the code, I created a variable to retrieve the value from my config file, along the lines of what the original user had done:
var config = context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
ILoggerFactory logger = new LoggerFactory().AddNLog();
var nlogConfigSection = config.Settings.Sections["MyService_NlogSettings"];
I set the variables that could be set, such as connection string etc. using the GlobalDiagnosticsContext, but obviously couldn't set the loglevel this way, due to its dislike of variables!
So instead, I did the following:
LogManager.Configuration.LoggingRules[0].SetLoggingLevels((NLog.LogLevel.FromString(nlogConfigSection.Parameters["AzureNLogLevel"].Value)),
NLog.LogLevel.FromString("Fatal"));
The 'SetloggingLevels' method expects values for Minlevel and MaxLevel of logging, hence my Config value was the min, and I hardcoded "Fatal" as the max since I was after a replication of 'minLevel' type logging, although obviously this too could have been set in my config file.

Spring Webflow Flow Registry Configuration

Please bear with me as this is my first question. Let me know what I can do to improve future questions.
I am trying to learn Spring Webflow, and am slowly wrapping my head around it. I am finding that there are a lot of conventions that the programmer is expected to "just know", and the examples online don't seem to work.
I have cobbled together one example that works as expected, but now I am trying to extend my understanding to the next level in another small project, with my long term goal being a much more complex application. The goal of this exercise is to build a login system that supports different types of client (phone, desktop, etc) with different webflows.
As near as I can tell, I am having trouble configuring the flow registry, probably because I am misunderstanding the convention.
The textbook example I am emulating is this:
<!-- The registry of executable flow definitions -->
<webflow:flow-registry flow-builder-services="flowBuilderServices"
id="flowRegistry" base-path="/WEB-INF/flows/">
<webflow:flow-location path="/welcome/welcome.xml" />
</webflow:flow-registry>
My configuration is this:
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices"
base-path="/WEB-INF/pages/">
<webflow:flow-location path="d/login.xml" />
<webflow:flow-location path="d/signup.xml" />
</webflow:flow-registry>
The log states:
DEBUG o.s.w.d.r.FlowDefinitionRegistryImpl - Registering flow definition 'ServletContext resource [/WEB-INF/pages/d/login.xml]' under id 'd'
DEBUG o.s.w.d.r.FlowDefinitionRegistryImpl - Registering flow definition 'ServletContext resource [/WEB-INF/pages/d/signup.xml]' under id 'd'
Since, under the covers, the flow registry is a simple HashMap, only one of the flow files is being registered, and not as what I would expect.
What am I missing?
Change configuration as mentioned below, this might help you:
<webflow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices"
base-path="/WEB-INF/pages">
<webflow:flow-location path="/d/login.xml" />
<webflow:flow-location path="/d/signup.xml" />
</webflow:flow-registry>
also see Spring Webflow - How to Get List of FLOW IDs

Mule expression variable scope

What is the scope of variables in Mule expression components, and how does that relate to flow variables? I had a flow with a set-variable and was surprised to see that the value was being overwritten by an assignment in an expression-component. For example,
<flow name="HelloWorldFlow1" doc:name="HelloWorldFlow1">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="9999" doc:name="HTTP"
doc:description="This endpoint receives an HTTP message." path="helloworld"/>
<set-variable variableName="asdf" value="firstvalue" doc:name="Variable"/>
<logger message="#[flowVars["asdf"]]" level="INFO" doc:name="Logger"/>
<expression-component doc:name="Expression"><![CDATA[asdf = "secondvalue";]]></expression-component>
<logger message="#[flowVars["asdf"]]" level="INFO" doc:name="Logger"/>
<expression-component doc:name="Expression"><![CDATA[qwer = "thirdvalue";]]></expression-component>
<logger message="#[flowVars["qwer"]]" level="INFO" doc:name="Logger"/>
</flow>
The output of this is:
INFO 2014-04-25 08:58:46,889 [[helloworld].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: firstvalue
INFO 2014-04-25 08:58:46,893 [[helloworld].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: secondvalue
INFO 2014-04-25 08:58:46,895 [[helloworld].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: null
If possible, can you point me to the documentation of the scoping rules? I've tried a few different searches and keep getting extraneous results.
Clarification: Within the expression-component, does Mule first check to see if there is a flow variable with a given name and then use that variable instead of creating a new one? If the expression component creates a variable, is the scope limited to just the expression component code? In http://blogs.mulesoft.org/mule-school-the-mulemessage-property-scopes-and-variables/, it says that Mule flow variables "behave like instance properties", but I can't find a definition for what an instance property is. The word scope is also not in the expression component reference page (http://www.mulesoft.org/documentation/display/current/Expression+Component+Reference).
With <set-variable you're creating a flow variable. Its scope is within flow it is declared and also sub-flows or private flow called by this flow. Think it of like as an instance variable.
Moreover, you've 4 logger statements in your flow while you're showing output of only 3 log statements. If you modify log statement to include what value you're printing, it will be less of confusion trying to figure out that print statement is for which variable like:
<logger message="Value of asdf is: #[flowVars['asdf']]" level="INFO" doc:name="Logger"/>
And you don't need to surround " arround your variable name. Other shorthand notation is to just say
<logger message="Value of asdf is: #[asdf]" level="INFO" doc:name="Logger"/>
For broader reference to scopes see this: http://blogs.mulesoft.org/mule-school-the-mulemessage-property-scopes-and-variables/
When you overwrite a variable value in a flow, initial value is overwritten by next assigned value just like a variable value assignment functions in java.
EDIT:
You're right, variables created by <set-variable> can be re-assigned with expression component but variables created inside <expression-component> doesn't have scope out side that block. Sorry I don't have links to back up with, this is based on my experiment.
Apart from what #Charu Khurana explained, I can see in our application that flow variables can be used by the parent flow. So, if you call a child flow from a parent flow(with <flow-ref> for example) and use <set-variable> inside, you will have access to these vars in your parent flow.

Bean Autowiring problem

I am starter in mutithreading. I am trying to index my data into solr.For that I was writing the following code
I am getting null pointer exception in the line highlighted
You need to add the following:
<context:annotation-config/>
You need to set the path for autowiring package scan and in your case it will be:
<context:component-scan base-package="a.b.c" />
After it you need to mark the class as candidate for autowiring:
#Component("indexTask")
#Scope("prototype")
IndexTask implements Callable<IndexObject>
{
//ommited
}
Next you can remove indexTask bean configuration from xml file. your package will be created automatically.
Hope it helps.
Autowiring doesn't happen automatically, you need to configure it. See the Spring docs for detail, but essentially you need to add
<context:annotation-config/>

Resources