Not able to set WorkItem State using TFS API? - tfs

I am trying to set State property value of Test Case Work item. I am creating using TFS API and C# code.
It throws an error while I save the test case using Save() method. I have called the Validate() method of a work item and the ArrayList shows the value I am trying to assign is an invalid state.
testCase.State = TestPointState.Ready.ToString();
ArrayList result = testCase.WorkItem.Validate();
if (!testCase.WorkItem.IsValid())
{
//this block executes
}
When I manually opened the MTM to see what are the different STATE values for existing work items, then I found READY and DESIGN. That's why I tried t assign TestPointState.Ready enum. I tried assiging READY string directly in that statement, but still the same exception whlie saving the test case.
Any idea on how to fix this issue ?

It is possible that when setting the state another field has then an invalid input. e.g.: when you change from Ready to Design it might require that you select who the AssignTo person is and so you'll need to populate these fields as well. You can use the Validate method to get a list of invalid fields after you set the state like below.
ArrayList invalidFields = newWI.Validate();

Related

Why Hybris modelService.save() doesn't work inside the ifPresent() method?

private void doSomething(someProcessModel process){
CustomerModel customer = process.getCustomerModel();
customer.getFoos().stream()
.filter(foo -> foo.getCountryCode().equals(process.getCountryCode()))
.findFirst()
.ifPresent(foo -> {
if(foo.getSomeNumber() == null){
foo.setSomeNumber("1234567");
modelService.save(foo);
}
});
}
As seen in the code snippet above, I have a 'CustomerModel' that has an attribute 'Foos'. It's a one-to-many relationship. As you can see I have done some filtering and in the end, I want to update the value of 'someNumber' attribute of 'Foo' if it is null. I've confirmed that everything is working as the "someNumber" attribute's value is updated during the debugging. It doesn't save at all as I have done my checking in the HMC. I have also validated that the Interceptor doesn't have any condition that would throw an error. There is nothing being shown in the log either.
I am wondering is it a legal approach to do the "modelService.save()' inside the 'ifPresent()' method? What could be the possible issue here?
I have found the root cause now as I have face the same issue again.
Context to my original question
To give more context to my original question, the #doSomething method resides in a Hybris Business Process action class and I have ended the action prematurely while I am debugging it (by stopping the debugging) once the #doSomething method is ran.
Root cause
The mentioned problem happened when I was debugging the action class. I assumed that the ModelService#save will persist the current state of the business process once it has been ran. However, the Hybris OOTB business process will do a rollback if there is any error (and I believe it was caused by me stopping the debugging half-way).
SAP Commerce Documentation:
All actions are performed inside their own transaction. This means that changes made inside the action bean run method are rolled back in case of an error.
Solution
Let the action runs completely!
Good to know
Based on the SAP Documentation and this blog post, there will be times that we will need to bypass a business process rollback even though there is an exception being thrown and there are ways to achieve that. More info can be found in this SAP Commerce Documentation and the mentioned blog post.
However, in some circumstances it may be required to let a business exception reach the outside but also commit the transaction and deal with the exception outside. Therefore, it is possible to make the task engine not roll back the changes made during a task which failed.
You have to be cautious with a list in models as they are immutable, you have to set the whole new list. Also you called save only on a particular model, which changes its Jalo reference, that's why your list is not updated. Mutating stream and collecting it in the end will create new list that's why you can stream over the list directly from the model.
private void doSomething(someProcessModel process){
CustomerModel customer = process.getCustomerModel();
ArrayList<FooModel> foos = doSomethingOnFoos(customer.getFoos());
customer.setFoos(foos);
modelService.saveAll(foos, customer);
}
//compare the value you know exists with something that might be NULL as equals can handle that, but not the other way around
private ArrayList<FooModel> doSomethingOnFoos(ArrayList<FooModel> fooList) {
return fooList.stream()
.filter(Objects::nonNull)
.filter(foo -> process.getCountryCode().equals(foo.getCountryCode()))
.filter(foo -> Objects.isNull(foo.getSomeNumber()))
.map(foo -> foo.setSomeNumber(1234))
.collect(toList());
}

Microsoft Graph fails when updating orderHint for a Planner bucket

I'm trying to update a Planner bucket's order. To do that, I set the orderHint value of that bucket to be <prevBucketOrderHint> <nextBucketOrderHint>!. This is the only change I make to the bucket object, however, when I try to save the changes, I get the following error:
Validation for field 'PlanId', on entity 'Bucket' has failed: This field is read only and cannot be changed
However, I'm not accessing nor modifying value of PlanId and therefore I don't understand why I get this error.
Below you can find the code I use to achieve my task (note that this is a C# code using the SDK and variable gc is a valid instance of Microsoft.Graph.GraphServiceClient):
theBucket.OrderHint = string.Format("{0} {1}!", previousBucket.OrderHint, nextBucket.OrderHint);
var etag = theBucket.GetEtag();
var result = gc.Planner.Buckets[bucketId].Request().Header("If-Match", etag).UpdateAsync(theBucket).Result;
Do you see any mistake in my approach or, alternatively, do you have any suggestions on how to change the order of buckets in a Planner plan?
Thanks
I'm guessing that you got theBucket object as the result of another call. The API endpoint expects a patch object that only contains the properties you want to update. You are sending the existing object as the patch object. The existing object theBucket has the planId set which is read-only at the service.
Fix it by creating a new PlannerBucket and only set the OrderHint property on it. Use the new PlannerBucket in the UpdateAsync method.

How to store data in workitem using key value pair in TFS using object model

I have heard that there is an api method available in TFS Object model api, through which i can store in the work item using key value pair and this data is not visible in UI as it is not any field value. This data can only be retrieved through api. I have searched but i was not successful up till now. If any one know such type of method so please share it.
My main purpose to store some metadata in it but it should not visible to the User and also user can not update it. Secondly i did not have to use any field, as fields vary from work item to work item and even from Process template to Process template.
Thanks in advance.
I suppose that you mean this link: https://www.visualstudio.com/en-us/docs/integrate/extensions/develop/data-storage.
To set a value of key-value you could use this method:
VSS.getService(VSS.ServiceIds.ExtensionData).then(function(dataService) {
// Get value in user scope
dataService.getValue("userScopedKey", {scopeType: "User"}).then(function(value) {
console.log("User scoped key value is " + value);
});
});
This document is the details information about the methods in VSS.ServiceIds.ExtensionData service.

How to update value in angular ui typeahead directive if no matching option is found

I've an array of objects containing title and salary which is used in typeahead directive.
I display department name and get entire object as value.
If none of the options match, I want user entered string to be converted to object still. Is there any way to update that?
This answer is pretty late, but I would just use ng-blur (to trap the end of the users input) along with a variable bound to typeahead-no-results. Then test if the variable is true in the method bound to ng-blur, and, if so, make an object out of the String supplied by the user and push it to your data source. Simple example found here.

Grails 2.3.7 Optimistic Locking version is updated every time a Command Object is submitted

I have the following
def save(ACommand command){
...
}
#Validateable
class ACommand implements Serializable
{
ADomainObject bundleDef
}
but every time save is called the version is incremented. So if I open up two browsers and submit a different value in succession, instead of getting an error the second time as I would expect, the value is updated.
I also tried using two different sessions with no difference
Update
If I use breakpoints and submit before the other one is completed it works fine. However, If I let the first complete then submit the second without a refresh the version is updated to the newer one (which I don't want) and the change goes through.
Update 2
When you perform updates Hibernate will automatically check the version property against the version column in the database and if they differ will throw a StaleObjectException. This will roll back the transaction if one is active.
per Grails this should work seems to me.
AFAIK, you need to check the version and handle failures yourself - it doesn't happen automatically. You can do this with code like this:
/**
* Returns a boolean indicating whether the object is stale
*/
protected boolean isStale(persistedObj, versionParam = params.version) {
if (versionParam) {
def version = versionParam.toLong()
if (persistedObj.version > version) {
return true
}
} else {
log.warn "No version param found for ${persistedObj.getClass()}"
}
false
}
you can call isStale from an action like this
def update() {
Competition competition = Competition.get(params.id)
if (isStale(competition)) {
// handle stale object
return
}
// object is not stale, so update it
}
I am not sure what you expect to happen but what you describe sounds correct to me unless you have code in your save() action that is relevant.
You can't expect Hibernate to do anything special here. When your save() action is invoked the instance is retrieved using Hibernate, mutated and then saved. That is all fine as far as Hibernate is concerned.
One way to deal with this is when the form for editing the entity is rendered, render the version of the entity that is being edited to a hidden form field which will be submitted when the entity is saved. In the save action after retrieving the entity from the database compare its version to the version retrieved from the hidden form field and if they don't match you know that the entity was modified between those 2 steps and you can react however is appropriate for your app. Note that since your example is using a command object, data binding is being imposed on the entity before your code ever executes. If that isn't what you want, don't use a command object.
I hope that helps.

Resources