Called Activity can not accept events - rhapsody

For my Rhapsody model I want to model a loop of actions in activitity Act2, which can be interrupted by an event. As activity Act2 is used in multiple places, I use the activity as a Call Behavior in activity Act1.
But I get the following error:
Called Activity can not accept events
AcceptEventAction : accepteventaction_19 in Pkg1::UseCases::UC1::Act2
CallBehavior : Act2 in Pkg1::UseCases::UC1::Act1
I'm unsure what I'm missing in my model?
I use Rhapsody 8.3.1

Looks like this is a limitation of my used version 8.3.1
Release notes of 8.4.0 state:
Activity diagrams: Call Behavior elements that reference activity diagrams that contain Accept Event Actions
Animation now supports activity diagrams with Call Behavior elements that reference activity diagrams containing Accept Event Actions (for C++ only)
EDIT:
I can confirm this problem was fixed in Rhapsody version 8.4.0

Related

Are there any restrictions or special requirements when calling a method in a backgroundWorker DoWork section?

This question is related to direction provided to me in another post (see How can I stop a method using a Cancel button in visual C#?). My question, is whether there are any restrictions when creating a BackgroundWorker, as far as called methods are concerned? I have a method that executes fine outside the DoWork section of my BackgroundWorker, but the moment it is placed inside the DoWork, I get a Cross Thread error stating "Cross-thread operation not valid: Control "txtFileOutput" accessed from a thread other than the thread it was created on." I know the BackgroundWorker is working with a basic for loop and have validated that. The "txtFileOutput" control referenced in the error is a textbox, to which I'm piping output from a regex query against a file (this is the method I'm trying to call within the DoWork).

Can connectSlotsByName connect to selection model changes?

In my main window (QMainWindow) I have a QTableView (named commandsTableView). Now I want to react on its selection changes.
I made a slot and connected it manually to ui.commandsTableView->selectionModel(). All works fine.
But then I thought: why not use auto-connection (especially that there will be more connections to be done)? At least it will add more force to consistent naming rules.
Yet I wasn't able to find proper name syntax. I tried:
on_commandsTableView_selectionModel_selectionChanged,
on_commandsTableViewSelectionModel_selectionChanged,
on_commandsTableView_selectionChanged,
on_commandsTableView___selectionChanged
but neither worked. In all cases there is there is a message on output when running the app (with corresponding slot name, here only first given as an example):
QMetaObject::connectSlotsByName: No matching signal for on_commandsTableView_selectionModel_selectionChanged(QItemSelection,QItemSelection)
(Why there are no assertions in response for connection errors - that I cannot understand. I lost much time wondering what is wrong before I spotted those - and alike - messages on output.)
The object returned by ui.commandsTableView->selectionModel() has an empty name. But setting it to selectionModel prior to making a call to connectSlotsByName doesn't help either.
According to the documentation connectSlotsByName() only supports signatures like
void on_<object name>_<signal name>(<signal parameters>);
According to the sources that's the only form it checks (watch how it collects a list of children, then matches parent's method names against names of the children).
Hence, to be able to use auto-connection you would have needed a named selection model, which would continue existing from the call to connectSlotsByName() onwards. Each time you change the selection model (not likely) or the model (likely) you'd have to name the selection model and auto-connect again. But alas connectSlotsByName() will duplicate all other connections as it doesn't seem to check if connections are unique, so we have to connect signals to such dynamic children as models, scenes etc manually.
I think it's
on_selectionModel_selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)

BPEL, initialize variable and repeating onAlarm eventHandler

I have a little problem I can't solve so far. In BPEL I want to create an onAlarm eventHandler which fires immediatly (i.e. the "for" element is set to 'PT0S') and repeats every 2 seconds. This eventHandler shall contain a counter which increments every time the alarm fires.
The question is: How to initialize the counter? If the variable will be initialized within the onAlarm scope the value would not increment anymore. In the "normal" control flow the value also cannot be initialized, because it is not defined if the process or the onAlarm scope runs first. So I would get every now and then an uninitializedVariable exception.
My solution would be to not initialize the variable neither in the process scope nor in the onAlarm scope, but create a faultHandler wherein the variable will be initialized and afterwards the onAlarm flow will be executed. Problem is every uninitializedVariable execution will be caught now by this faultHandler and there may be another too.
So is there another possibility to deal with this problem or can I somehow find out which variable wasn't initialized properly so the faultHandler can get two control flows?
The solution should work on every BPEL engine.
Thanks, Michael
You can initialize a variable with a default value on its definition using a from-spec just like in an assignment. See section 8.4.1 of the spec for the details.
A default initialization can look like this:
<variables>
<variable name="Default" type="xsd:int" >
<from>5</from>
</variable>
</variables>
This should work as eventHandlers are installed after the start activity of a process has completed. By then, the variables defined in the root scope have already been initialized. To quote the spec, section 12.1:
Scope initialization consists of instantiating and initializing the
scope's variables and partner links; ... If a scope contains an
initial start activity then the start activity MUST complete before
the event handlers are installed.
So much for spec. I think nobody can tell whether this "works on every BPEL engine". As far as I know, it works on bpel-g, Orchestra and EasyBPEL, but not on Apache ODE or OpenESB.

How to assign Custom Activity Result to a Root level variable at Runtime (in Custom Activity Execute method) in workflow?

Assume that I have a workflow with 3 Custom Activities which are placed in a Sequence Activity. And I created a Boolean variable (name it as “FinalResult”) at Sequence Activity level (Root) to hold the Result. My Intention is, I want to assign each Custom Activity Result to Root level variable (“FinalResult”) within the Custom Activity Execute method after finishing the activity.
I can get this by declaring the output argument in Custom Activity and placing the variable name at design time in the properties window of activity manually while designing the policy.
But I don’t want to do this by the end user. I want just the end user drag and drop the activities and write conditions on the” FinalResult” variable. Internally I have to maintain the Activity Result in “FinalResult” Variable through programmatically.
Finally I want to maintain the workflow state in “FinalResult” variable and access it anytime and anywhere in the workflow.
I tried like this below getting error "Property does not exist".
WorkflowDataContext dataContext = context.DataContext;
PropertyDescriptorCollection propertyDescriptorCollection = dataContext.GetProperties();
foreach (PropertyDescriptor propertyDesc in propertyDescriptorCollection)
{
if (propertyDesc.Name == "FinalResult")
{
object data = propertyDesc.GetValue(dataContext);// as WorkUnitSchema;
propertyDesc.SetValue(dataContext, "anil");
break;
}
}
Please let us know the possible solutions for the same.
I do this all the time.
Simply implement IActivityTemplateFactory in your activity. When dragged and dropped onto the design surface, the designer will determine if your activity (or whatever is being dropped) implements this interface. If it does, it will construct an instance and call the Create method.
Within this method you can 1) instantiate your Activity and 2) configure it. Part of configuring it is binding your Activities' properties to other Activities' arguments and/or variables within the workflow.
There are a few ways to do this. Most simply, require these arguments/variables have well known names. In this case, you can simply bind to them via
return new MyActivity
{
MyInArgument = new VisualBasicValue<object>(MyActivity.MyInArgumentDefaultName),
};
where MyActivity.MyInArgumentDefaultName is the name of the argument or variable you are binding to.
Alternatively, if that variable/argument is named by the user... you're in for a world of hurt. Essentially, you have to
Cast the DependencyObject target passed to the Create method to an ActivityDesigner
Get the ModelItem from that AD
Walk up the ModelItem tree until you find the argument/value of the proper type
Use its name to create your VisualBasicValue
Walking up the ModelItem tree is super duper hard. Its kind of like reflecting up an object graph, but worse. You can expect, if you must do this, that you'll have to fully learn how the ModelItem works, and do lots of debugging (write everything down--hell, video it) in order to see how you must travel up the graph, what types you encounter along the way, and how to get their "names" (hint--it often isn't the Name property on the ModelItem!). I've had to develop a lot of custom code to walk the ModelItem tree looking for args/vars in order to implement a drag-drop-forget user experience. Its not fun, and its not perfect. And I can't release that code, sorry.

Statefinalization/initialization activity only runs on leaf states

I am trying to get my Windows State Machine workflow to communicate with end users. The general pattern I am trying to implement within a StateActivity is:
StateInitializationActivity: Send a message to user requesting an answer to a question (e.g. "Do you approve this document?"), together with the context for...
...EventDrivenActivity: Deal with answer sent by user
StateFinalizationActivity: Cancel message (e.g. document is withdrawn and no longer needs approval)
This all works fine if the StateActivity is a "Leaf State" (i.e. has no child states). However, it does not work if I want to use recursive composition of states. For non-leaf states, StateInitialization and StateFinalization do not run (I confirmed this behaviour by using Reflector to inspect the StateActivity source code). The EventDrivenActivity is still listening, but the end user doesn't know what's going on.
For StateInitialization, I thought that one way to work around this would be to replace it with an EventDrivenActivity and a zero-delay timer. I'm stuck with what to do about StateFinalization.
So - does anyone have any ideas about how to get a State Finalization Activity to always run, even for non-leaf states?
Its unfortunate that the structure of "nested states" is one of a "parent" containing "children", the designer UI re-enforces this concept. Hence its quite natural and intuative to think the way you are thinking. Its unfortunate because its wrong.
The true relationship is one of "General" -> "Specific". Its in effect a hierachical class structure. Consider a much more familar such relationship:-
public class MySuperClass
{
public MySuperClass(object parameter) { }
protected void DoSomething() { }
}
public class MySubClass : MySuperClass
{
protected void DoSomethingElse() { }
}
Here MySubClass inherits DoSomething from SuperClass. The above though is broken because the SuperClass doesn't have a default constructor. Also parameterised constructor of SuperClass is not inherited by SubClass. In fact logically a sub-class never inherits the constructors (or destructors) of the super-class. (Yes there is some magic wiring up default constructors but thats more sugar than substance).
Similarly the relationship between StateAcivities contained with another StateActivity is actually that the contained activity is a specialisation of the container. Each contained activity inherits the set of event driven activities of the container. However, each contained StateActivity is a first class discrete state in the workflow same as any other state.
The containing activity actual becomes an abstract, it can not be transitioned to and importantly there is no real concept of transition to a state "inside" another state. By extension then there is no concept of leaving such an outer state either. As a result there is no initialization or finalization of the containing StateActivity.
A quirk of the designer allows you to add a StateInitialization and StateFinalization then add StateActivities to a state. If you try it the other way round the designer won't let you because it knows the Initialization and Finalization will never be run.
I realise this doesn't actually answer your question and I'm loath to say in this case "It can't be done" but if it can it will be a little hacky.
OK, so here’s what I decided to do in the end. I created a custom tracking service which looks for activity events corresponding to entering or leaving the states which are involved in communication with end users. This service enters decisions for the user into a database when the state is entered and removes them when the state is left. The user can query the database to see what decisions the workflow is waiting on. The workflow listens for user responses using a ReceiveActivity in an EventDrivenActivity. This also works for decisions in parent ‘superstates’. This might not be exactly what a "Tracking Service" is meant to be for, but it seems to work
I've thought of another way of solving the problem. Originally, I had in mind that for communications I would use the WCF-integrated SendActivity and ReceiveActivity provided in WF 3.5.
However, in the end I came to the conclusion that it's easier to ignore these activities and implement your own IEventActivity with a local service. IEventActivity.Subscribe can be used to indicate to users that there is a question for them to answer and IEventActivity.Unsubscribe can be used to cancel the question. This means that separate activities in the State's inialization and finalization blocks are not required. The message routing is done manually using workflow queues and the user's response is added to the queue with appropriate name. I used Guid's for the queue names, and these are passed to the user during the IEventActivity.Subscribe call.
I used the 'File System Watcher' example in MSDN to work out how to do this.
I also found this article very insructive: http://www.infoq.com/articles/lublinksy-workqueue-mgr

Resources