It's all about the answers!

Ask a question

Workspace deliver and accept flow entries , help! [resolved]


sam detweiler (12.5k6195201) | asked Feb 04 '14, 3:23 p.m.
retagged Feb 04 '14, 4:54 p.m. by Sonia Dimitrov (27159)
 in my migration utility, I need to remap the flow entrys to point to local server artifacts.

getAcceptSources() and getFlowtargets() make sense.
I can manage those lists..

then there is get default/current AcceptFlow(), and get default/current Deliverflow().
no problem..

but set is ?

+ setCurrent(IFlowEntry entry)  
          Indicates that the specified entry is the current one for the workspace for this direction (Accept or Deliver).
setDefault(IFlowEntry entry)  
          Indicates that the specified entry is the default one for the workspace for this direction (Accept or Deliver).

what is the 'for this direction'? the flow TABLE contains both. as per above.. 

Accepted answer


permanent link
Tim Mok (6.6k38) | answered Feb 04 '14, 4:04 p.m.
JAZZ DEVELOPER
The part about direction is not applicable at the moment. Flow targets are considered bi-directional and will not restrict users from delivering or accepting. If you're flowing to a target and have permission, you can deliver or accept. There are no one way flows. Accept flows are not used at the moment to enforce direction.
sam detweiler selected this answer as the correct answer

Comments
sam detweiler commented Feb 04 '14, 4:40 p.m.

great, thanks..  I'll comment out my accept flow support.  


sam detweiler commented Feb 05 '14, 7:00 a.m. | edited Feb 05 '14, 8:09 a.m.

I have a followup question.

when we duplicated the workspaces from server 1 to server 2, I didn't notice the flow target info.
so it was not updated.  so the workspace handles are from server1's repository..
now we have duplicated the workspaces to server 3.  I have a manual mapping file (uuids of workspaces on server 1 to workspace name on server 3)
now I need to fix the workspaces in the flow targets.

the UI lets me remove ONE of potentially many. 'missing 'uuid'"

but the only api I see are


 void removeAll(IFlowNodeHandle target)
          Removes all flow entries that have the given node as a deliver target or as an accept source.
 void removeDeliverFlow(IFlowNodeHandle target)
          Removes flow entries that have the given node as a deliver target.

but the handle is invalid for this repository, and an exception is thrown.
I haven't tried to look at the product source yet for the workspace editor


Tim Mok commented Feb 05 '14, 8:23 a.m.
JAZZ DEVELOPER

Can you post the exception that you're getting and maybe a snippet of your code? That might help determine why it didn't work.

If you're ok logging in to all of your servers at the same time, you can do that from the Eclipse client to resolve the flow targets. Any that are still unresolved don't exist and can be removed and you'll be able to see the ones that you want to remove.


sam detweiler commented Feb 05 '14, 9:23 a.m.

thanks for making me look closer.. I was trying to use the workspace handle instead of the flownode entry.

(never ignore the requirement for an explicit cast!)

I can't ask the 200 developers to fix my mistake. 
 


sam detweiler commented Feb 05 '14, 12:29 p.m.

sorry, I must be blind.. where is save workspace?


I can see load, create, delete, but no save. I would have expected it to be on the workspacemanager..  


sam detweiler commented Feb 05 '14, 5:25 p.m.

 seems this is built in.. you change the description and the workspace gets updated..

same with the flowtable..


sam detweiler commented Feb 05 '14, 5:52 p.m.

one more small question.. 


if there is only 1 flow entry, is it required to set current and default? 


Tim Mok commented Feb 06 '14, 8:47 a.m.
JAZZ DEVELOPER

The Eclipse workspace editor has its own notion of a working copy. When the user saves, the necessary operations are performed on the workspace to give the user a feeling of editing and saving a workspace as a transaction.

The current flow entry and default flow entry is not required. However, it is useful so that RTC clients can select and identify flow targets if no flow target is specified. If you're writing code, workspace comparisons and deliver/accept operations require a target to be specified. There is no API that will automatically perform those operations using the current or default flow target.

In terms of what users would care about, the current flow target is what the Eclipse Pending Changes shows. The default is used for letting the user quickly select the specified default flow target when changing flow targets. Users can set these in the workspace editor.


sam detweiler commented Feb 06 '14, 9:29 a.m. | edited Feb 06 '14, 10:38 a.m.

thanks.. the workspace I am looking at has one target stream. and its set as current and default.  the stream handle is not valid, cause it is on a repository we cannot connect to. 


there is ONE flowentry for delivertargets 
                                                        List<IFlowEntry> targets = (List<IFlowEntry>)dev_flowtable.deliverTargets();
                                                        // loop thru the tagets, if any
                                                           for(int i=0; i<targets.size();i++)
(there is a bug here in dev_flowtable.deliverTargets(), the second time thru the loop
it returns null instead of an empty List<> after I have deleted the only flowentry.
 java.util.List deliverTargets()  
          Returns all deliver targets in table.
this causes the shorthand
for(IFlowEntry target:dev_flowtable.deliverTargets()){}
to cause a null pointer exception when the table is empty. .
(same for acceptsources)

AND, when u delete the ONLY flowentry, the current/default are reset to empty
BEFORE u can process them ..

my code does
fixup the targets
fixup the sources
fixup default
fixup current

default and current are always not set by the time my code gets there.

they ARE set on the way in. this is a bad side effect. 

I 'think' the only way out of this is to 
read the old entries, figure out how they map
ADD a new flowentry(s),
figure out what should be new/current from the old to the new 
set the current and default,
then REMOVE the bad flowentry(s).

on the other hand, if there is only ONE flowentry, then by default is MUST BE current and default
so the analogous config should be done (set them, you removed them when they were the only, and the only was removed)
 dev_flowtable.removeDeliverFlow(target.getFlowNode()); 


Tim Mok commented Feb 06 '14, 10:38 a.m.
JAZZ DEVELOPER

I don't see how removing the last flow table entry causes #deliverTargets() to return null. You might want to open a bug report about this and state platform and the JVM version that you're using. This might be something specific to your configuration. The #deliverTargets() method calls Collections#unmodifiableList(..) and if the deliverTargets list was null then that would NPE.

I'm not sure what you expect from the current and default flow targets. If your cleanup removes flow targets that are current or default then those will be unset. The Javadoc might not be clear enough but calls to remove a flow target state they will remove all flow entries for the specified target.

Also, it is valid for there to be no current or default flow target. The Javadoc is clear that getting those entries may return null. The Eclipse client does add a current flow when the workspace has its first flow target set. However, manipulating the flow table yourself will not set a current or default flow target automatically for you.


sam detweiler commented Feb 07 '14, 6:05 p.m.

I am still having trouble setting current/default

I got the flow table working copy and am processing that. there is one FlowEntry,
and its set current/default.

if I delete the one entry then current/default get cleared, so I have to save the fact and detail in case there are more than one flow entry when processed later.

if I delete the one flow entry, then try to unset current or default, I get an exception, cause its not set (see the cleanup side effect above).

so I add the new flow entry with the right workspace connection.
Now I want to set IT as current..
but I don't have its FlowEntry object.
so I have to loop back thru the table to get it out..
but using THAT to set the default, throws an exception, cause it appears I haven't written the flow table back yet, and the objects don't match. (the check flowintable returns false).

I don't see a method to add  by passing a flowentry  (create one, add it, make it default/current)


Tim Mok commented Feb 10 '14, 8:54 a.m.
JAZZ DEVELOPER

Can you provide a snippet of your code where you set the current or default flow entry or even the exception message? It's hard to tell if there's anything wrong with your code without looking at it or seeing the error.

You don't have to unset the current or default if the entry was removed from the flow table. It would be better to check if a current or default is set and set one if there is none. To get your flow entry, you can use the workspace handle and call IFlowTable#getDeliverFlow(..) to get the flow entry that you just added. Then add this entry as the current and default flows.

showing 5 of 12 show 7 more comments

2 other answers



permanent link
sam detweiler (12.5k6195201) | answered Feb 10 '14, 1:20 p.m.
edited Feb 23 '14, 6:53 a.m.
ok, other issues resolved. I missed getDeliverFlow(..)

back to the problem where the loop style 
for(IFlowEntry target: flow_table.getDeliverTargets())
{
}

fails null pointer exception (rtc 4.0.4)

the scenario

the workspace was copied from system 1 to system 2 using the copy workspace function (shown at top of code below)
the flow table was NOT updated. the target UUID does not exist in the database.
the system was upgraded from 3.0.1 to 4.0.4
and the same code was used to copy from system2 to system 3. 
now we are trying to fixup the flowtargets. the users may  have modified 'some' of them 
and not others. 

(1) loop thru flow targets
(2) try to get a connection to the targets recorded stream
prodiws = prodmgr.getWorkspaceConnection((IWorkspaceHandle) (target.getFlowNode()), null);

(3) if there is an exception (CRJAZ0215E The following record was not found in the database:)
(4) document this case in the workspace description, 
(5) remove this entry from the flow table
(1) and then loop to handle any more flow table target entries
(6) null pointer exception in  
collections class 
public Iterator<E> iterator() {
   return new Iterator<E>() {
Iterator<? extends E> i = c.iterator();

public boolean hasNext() {return i.hasNext();}  ---- returned true (should have returned false)
public E next() {return i.next();}  ----> fails null pointer. ChkForComodification() fails. 
public void remove() {
   throw new UnsupportedOperationException();
                }
   };
        }


try
{
                                                   new_devworkspace= devmgr.copyWorkspace(devowner, prodworkspace,  workspacename,
                                                            prodworkspace.getDescription(), ourlogger);
                                                  
                                                  // get the table working copy so we can update it
                                                  IFlowTable dev_flowtable=new_devworkspace.getFlowTable().getWorkingCopy();
                                                       
                                                  // loop thru the flow targets, if any  , non-volatile list                                                                 -------> fix                      IFlowEntry[] targets = (IFlowEntry[]) dev_flowtable.deliverTargets().toArray(new IFlowEntry[dev_flowtable.deliverTargets().size()]);
                             ----> (1)            for(IFlowEntry target : targets)
                                                       {                                                           
                                                      IWorkspaceConnection prodiws =null;
                                                           try 
                                                           {
                                                          // connect to the production workspace
                               (2)                            prodiws = prodmgr.getWorkspaceConnection((IWorkspaceHandle) (target.getFlowNode()), null);
                                                               // find production workspace by name in dev system
                                                               IWorkspaceConnection devtargetStream=finddevStreambyname(devstreams,prodiws.getName());
                                                          // if the stream is present on the target system   
                                                               if(devtargetStream!=null)
                                                               {
                                                                   // update a flow table with the dev system pointers
                                                              // add the local system handle instead           
                                                              dev_flowtable.addDeliverFlow(devtargetStream.getResolvedWorkspace(), devrepo.getId(), devrepo.getRepositoryURI(), null, prodiws.getDescription());
                                                              IFlowEntry newnode = dev_flowtable.getDeliverFlow(devtargetStream.getResolvedWorkspace());                                                                   
                                                              // record if this target flow node was current or default
                                                          if(target.equals(dev_flowtable.getCurrentDeliverFlow()))
                                                          {
                                                          dev_flowtable.setCurrent(newnode);
                                                          }
                                                          if(target.equals(dev_flowtable.getDefaultDeliverFlow()))
                                                          {
                                                          dev_flowtable.setDefault(newnode);
                                                          }                                                                   
                                                               }
                                                               else
                                                               {
                                                              new_devworkspace.setDescription(new_devworkspace.getDescription()+"\n missing deliver target stream=\""+prodiws.getName()+"\" removed", null);
                                                               }
                                                           }
                                                           catch(Exception ex)
                                                           {
                                   (3)                        System.out.println("find flow target workspace failed exception="+ex.getMessage());
                                                          // catch the bad workspace handle
                                                          // remove the bad info 
                                                          //  and indicate we removed it   
                                                           (4) new_devworkspace.setDescription(new_devworkspace.getDescription()+"\n unresolvable deliver target ="+target.getFlowNode().getItemId()+" removed", null);                                                                                                                             
                                                           }
                                                           // remove it
                            ======>(5)            dev_flowtable.removeDeliverFlow(target.getFlowNode());
                                                       }  // end of loop
                                                       // save the updated flow table, no more targets to update                                                  
                                                       new_devworkspace.setFlowTable(dev_flowtable, null);
                                                   } 
                                                }
                          (6)                      catch (Exception ex)
                                                {
                                                    System.out.println("\t\tCopy Workspace " +  workspacename
                                                            + " failed, exception=" + ex.getMessage() + " time="
                                                            + sdf.format(Calendar.getInstance().getTime()));
                                                        if(ex.getMessage().contains("error occurred: \"java.net.SocketTimeoutException\""))
                                                        {
                                                            System.out.println("connection timeout, login and try again");
                                                            devServer.logout();
                                                            devServer.setConnectionTimeout(devServer.getConnectionTimeout()+one_hour);                                                            
                                                            devServer.login(null);
                                                            productionServer.logout();
                                                            productionServer.setConnectionTimeout(productionServer.getConnectionTimeout()+one_hour);                                                            
                                                            productionServer.login(null);
                                                            devmgr.deleteWorkspace( (IWorkspaceHandle) new_devworkspace, ourlogger);
                                                            ex.printStackTrace();
                                                        }
                                                }

Comments
Tim Mok commented Feb 10 '14, 2:48 p.m.
JAZZ DEVELOPER

I would open a bug against Source Control about this. It looks like you get the NPE when you copy a workspace from server 1 to server 2 and call #deliverTargets() on the copy's flow table. Include the version and type of VM that you're using. It looks like the error occurs in the iterator, which may be an issue in RTC or in the VM.


sam detweiler commented Feb 10 '14, 3:39 p.m.

and it only happens when you try to connect to the bad flow node first. 

otherwise it works fine. (most of mine have bad flow nodes of course).. 

its IBM's OOtB rtc/clm installs.. 




sam detweiler commented Feb 12 '14, 11:39 a.m.

user error.. I was modifying the list over which an implied iterator was traversing.  


sam detweiler commented Feb 23 '14, 6:53 a.m.

fix posted to the above code lest anyone copy it


permanent link
sam detweiler (12.5k6195201) | answered Feb 11 '14, 10:19 a.m.
 hopefully one last question. 

I have two eclipse configurations.  one with the 3.0.1 p2, one with the 4.0.4 p2

using 3.x to look at a workspace on 3.x I see (default)(current)
using 3.x to look at a copy of the workspace after a duplicate on system upgraded to 4.x I see (default)

then I replicate the workspace to another 4.0.4 system, and in the fixup, current is not set, but default is.  

I debugged into the flowtable,  dev_flowtable.setDefault(newnode);
and I see it is added to the 'defaults' list. 

later when I use the workspace editor, (default) is not shown. 
if I set it manually in the editor, and then save, close the editor, open editor, 
'default' is not shown again. 
if I sent both default and current manually.. only '(current)'  is shown. 

is this a UI bug? or a known change of behavior?

if I look at a workspace created on the end system, both (current) and (default) are shown. 

Your answer


Register or to post your answer.