MSDeploy and when it just stops working
On my current project, we have a Bamboo continuous integration server that deploys an ASP.net application packaged with MSBuild to our dev integration IIS server. This deployment happens via MSDeploy using the following command in the MSBuild script:
"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -source:package='path\to\the.zip' -dest:auto,wmsvc='https://iisserver:8172/msdeploy.axd?Site=MySite',userName='*****',password='*****',includeAcls='False' -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:path\to\the.SetParameters.xml -allowUntrusted
Everything is good with the command and deployments to iisserver were happening many times a day for a few months. Then the other day, the dev integration deployment job started failing with the following error:
Error: (build date) An error occurred when the request was processed on the remote computer.
Error: Unable to perform the operation. Please contact your server administrator to check authorization and delegation settings.
Nice error! Very informative. So I go ahead and check all the usual things: did a code change break something (no); did the user account represented by userName in the command get locked (no), or did its password expire (no); was the wmsvc agent running on the server (yes); were any Windows updates installed on the server (yes, on the same day the deployment started breaking); were there any changes to the Window or IIS server configuration (no)
With these checks done, the only one that seemed possible was one of the Windows updates might have done it. So I backed out the updates. But that didn’t fix the issue. Hmm, alright. After quite a bit of effort and time expended by myself and our systems administrators, I finally dug up this StackOverflow issue that sounded similar. The answer is what caught me:
…Turns out that when you install web deploy it sets up two local accounts WDeployConfigWriter and WDeployAdmin. These passwords on these accounts are set to expire…
Ah ha! Wait, what?! In addition to the domain service account I use on the command line, there are 2 more local accounts required by the tool? That I didn’t know were there? And they had passwords set to expire after 90 days? Really? Awesome. In any case, after “fixing” those two accounts on the dev integration server, they deployments started working as they had before.
Having shared functionality/pages across software modules in web application development seems to be a common occurrence (at least within the projects on which I am working) and is a problem that can be handled in a number of ways. Currently, I happen to be implementing two different user modules in a Grails 2.0.x application that ended up needing such shared functionality, so I thought I would share my solution. I am going to describe how I initially developed the modules, and how I solved the problem of having a required common interstitial form page that is shared between the two or more page flows.
The first module
The page flow within the first module is as described in Figure 1 below:
When developing the module, both web page forms represented by the 2nd and 3rd steps in the flow were implemented within the same controller class (following the practice of Agile development of implementing what you need right now, and refactoring when circumstances require you to do so). Everything good so far, this is all standard web application development. Story complete, so let’s look at the second module.
The second module
The page flow within the second module is as described in Figure 2 below:
Note that the 2nd step in both Figure 1 and Figure 2 both note that some user input is required before the actual function can commence. As it turns out, the user input required is identical, meaning the exact same form data is captured from the user. This is depicted in Figure 3:
In “traditional” (read: lazy) web development, I might just copy all of the logic for displaying the form and capturing the input from the Option1 controller(s) within Module A into the Option 2 controller(s) within Module B. But I figured it could be implemented so much more cleanly without the need for any code duplication. The solution I decided upon was to implement the logic for determining the need to direct the user to the interstitial page within a Grails Filter.
The solution
Let’s take a look at the Filter class that determines whether the user is required to be directed to the interstitial page.
RequiredAttributeFilters.groovy
class RequiredAttributeFilters {
def filters = {
attributeRequiredforOptionA(controller: 'optionA', action: 'index') {
before = {
if(session.someAttribute == null) {
// attribute not set, redirect user to collect data
def targetUri = request.forwardURI.replace(request.contextPath, '')
session.requiredAttributesFilterRedirectUri = targetUri
redirect controller: 'requiredUserInput', action: 'index'
}
}
}
attributeRequiredforOptionB(controller: 'optionB', action: 'index') {
before = {
if(session.someAttribute == null) {
// attribute not set, redirect user to collect data
def targetUri = request.forwardURI.replace(request.contextPath, '')
session.requiredAttributesFilterRedirectUri = targetUri
redirect controller: 'requiredUserInput', action: 'index'
}
}
}
removeSomeAttribute(controller: 'user', action: 'menu') {
before = {
// user exited current function, remove required attribute
session.someAttribute = null
}
}
}
}
This is just a standard Grails filter class that intercepts requests to “/option1/index” and “/option2/index” and redirects the user to “/requiredUserInput/index” if the value of session.someAttribute is null. Before redirection, it stores the value of the URL that user initially requested in the session. It also removes the attribute from session if the user exits current function (in my case, goes back to their menu). Now that we have the filter is place, let’s look at the controller that captures the required user input.
RequiredUserInputController.groovy
class RequiredUserInputController {
def index = {
// do stuff
// render view
render view: 'index'
}
def captureData = {
// check form errors etc.
def someAttribute = null;
// get the data and set the attribute in session
session.someAttribute = someAttribute
redirect uri: session.requiredAttributesFilterRedirectUri
}
}
The above controller has two methods: the standard “index” method for rendering the form and the “captureData” method, which is called upon form submission. The latter performs any required form processing, and in addition, sets the value of session.someAttribute to the correct current value. It then redirects to the URL that was set in session by the filter that redirected here in the first place. The filter is called again, but session.someAttribute has a value so filter processing is skipped. I won’t detail the GSP code for the form page, but it contains a simple form whose action attribute points to the “captureData” URL.
That’s all there is to it. If in the future additional page flows need to same data in order to proceed, those controllers/actions/URIs just need to be added to the Filter class so that the interception occurs.
Grails 2.0 mockFor() Gotcha
Update: When I was researching another Grails issue, I found out that what I encountered below looks to be fixed in Grails 2.0.1. I have yet to verify the fix, but if you also encounter this issue I urge you to try Grails 2.0.1 to see if it resolves the problem.
I am working on a Grails 2.0.x project and am quite enjoying some of the new features that are part of the current Grails release. The new test mixins that are part of Grails 2.0.x are awesome and really simplify the creation of your unit test classes. But I ran across a “gotcha” when using the test mixins.
I was writing a unit test class for a Grails controller, and was using the default template that gets created via:
grails create-controller com.asoftwareguy.example.Example
One of the helper methods exposed by the GrailsUnitTestMixin is the mockFor() method, which is a simplified way of creating a new Groovy mock. I though this to be much cleaner than needing to instantiate a new MockFor() every time I needed a mock proxy for an interface. However, I ran into an issue where the proxy instances created by the mockFor() method of the mixin are not cleaned up between test case runs. Let me give an example of what was failing.
ExampleController.groovy
package com.asoftwareguy.example
class ExampleController {
def exampleService
def index() {
def something = exampleService.doSomething()
render (view: 'index', model: [something: something])
}
}
ExampleService.groovy
package com.asoftwareguy.example
interface ExampleService {
List doSomething();
}
ExampleControllerTests.groovy
package com.asoftwareguy.example
@TestFor(ExampleController)
class ExampleControllerTests {
void testDoSomething_first_time() {
def mockService = mockFor(ExampleService) //use the mixin
mockService.demand.doSomething() { ->
return true
}
controller.exampleService = mockService.createMock()
controller.index()
// assertions
}
void testListStations_second_time() {
def mockService = mockFor(ExampleService) //use the mixin
mockService.demand.doSomething() { ->
return true
}
controller.exampleService = mockService.createMock()
controller.index()
// assertions
}
}
With the above code in place, the first test case would always pass, but the second test case would fail with the following error:
| Failure: testListStations_second_time(com.asoftwareguy.example.ExampleControllerTests) | junit.framework.AssertionFailedError: No more calls to 'doSomething' expected at this point. End of demands. at grails.test.MockClosureProxy.doBeforeCall(MockClosureProxy.java:66) at grails.test.AbstractClosureProxy.call(AbstractClosureProxy.java:74) at com.asoftwareguy.example.ExampleController.index(ExampleController.groovy:xx) at com.asoftwareguy.example.ExampleControllerTests.testListStations_second_time(ExampleControllerTests.groovy:xx) | Completed 2 unit tests, 1 failed
After some troubleshooting and debugging the issue, I have concluded that there is a bug in the version of Grails I running (2.0.0) and hopefully it is fixed in the next release. As a workaround, I have reverted to instantiating new MockFor() instances within each test case.
I am working on a Grails 2.0.x application that needs to consume some web services. Simple enough, I have written many clients in the past, using Axis and Spring-WS in Java, and WCF in .Net. Almost everything I have done so far was easy with Grails and Groovy, so I set out to create a client in Grails.
First off, I found GroovyWS and discovered the ease in which one can create clients with this tool. All was well when running Grails locally, but when the application deployed to our dev integration server (Tomcat 6, Java 6), it was throwing some exceptions about not finding the JAXB types for the specified class name. Apparently, the JAXB implementation on the dev integration was creating classes of different names than the implementation running on my local machine, from the same WSDL. I started debugging but quickly found myself in dependency hell, so I stepped back and tried a different client.
I had used Spring-WS before on a Spring 2.5 Java project and knew how it worked, so I gave it a shot. Even with this implementation, I was getting errors and again finding myself in dependency hell. There was still one more client I had used in the past, so I thought I would give it a try. Running wsdl2java against Axis 1.4 resulted in a client where classes actually would not compile. I attribute this to the complexity of the service itself and Axis’ inability to correctly parse out the types correctly. In any case, no dice on Axis 1.4.
Then I remembered JAX-WS. It is the most up-to-date web service tool supported by Java. After some issues with wsimport failing to generate a client at all (the WSDL has not WS-I BP 1.1 compliant and was later fixed by the service developer), I was able to successfully generate the client. I integrated it with my code, fired up Grails, invoked the service and bam!:
runtime modeler error: SEI rsastationinventorymgmtcontract.StationInventoryMgmtPT has method __execute annotated as BARE but it has more than one parameter bound to body. This is invalid. Please annotate the method with annotation: @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
What?! So JAX-WS doesn’t know how to correctly generate a client from a WSDL? I was doubtful and wanted to prove it worked. I created a simple Java application containing the source files for the generated client and a single Java class to test the service. I fired up the 1.6 JVM and ran the class, and lo and behold, the client invoked the service successfully. Then I thought, ‘Oh no, more dependency issues?!’ Then I thought of something. What if I ‘forced’ the JAX-WS implementation used at runtime? Surely that would help, right? I added the following to the Grails BuildConfig.groovy:
grails.project.dependency.resolution = {
...
dependencies {
...
runtime('com.sun.xml.ws:jaxws-rt:2.1.4')
}
}
I built the application and fired up Grails, and was able to invoke the service successfully.
All in all, I have been happy with my development experience in Grails, but dealing with web service clients left me wanting more from the framework in this area. Maybe it is just my unfamiliarity with the framework, but this solution was not obvious to me and left me scratching my head for a while.
A Groovy way to mask data
I was working on some code where I needed to mask data, and the application was being written in Groovy. I came up with this (what I think is a) neat trick to do it, using regular expressions and lambda expressions/closures.
package example
class Model implements Serializable {
...
String value
...
def valueMasked() {
return value.replaceFirst('.*(?=.{4})', { match ->
return "".padLeft(match.length(), '*')
});
}
}
I was helping out a co-worker of mine construct a script to find/count occurrences of a given string that occur on a line preceding another given string. Using GNU grep, this would be easy:
grep -B 1 tofind FILE_PATTERN | grep -c tofindabove
Unfortunately, Solaris does not use GNU grep, so I had to resort to using nawk + grep:
nawk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=1 a=0 s="tofind" FILE_PATTERN | grep -c tofindabove
where within the nawk command,
b: number of lines before match to display
a: number of lines after match to display
s: string to match
Credit for the usage of the nawk command in this context.


