Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Web CMS (TeamSite)
SubmitTask vs. ExternalTask calling iwsubmit
System
I need to determine whether to implement submit in workflow as a SubmitTask or an ExternalTask calling iwsubmit. Below are the pros and cons I have come up with. Is anyone using iwsubmit instead of SubmitTask, or can you come up with additional pros and cons? I think the biggest ones are that I can't control the comment (without an externaltask to iwrmtaskfile and iwaddtaskfile with a new comment), and that the conflict resolution cannot be shared to a group (plus the UI is pretty bad for non-technical users).
Thanks,
-John
2.1 Benefits of Using SubmitTask
· Graphical user interface for conflict resolution
· Typical TeamSite implementation
2.2 Drawbacks of Using SubmitTask
· A conflict occurs when a user in one workarea edits a file that is not current or has been checked out into another workarea. Conflict resolution screen only appears at Submit time – right before content goes to production. This is a bad time to discover conflicts.
· Conflict resolution task can only be associated with a single user, so if that user is out of the office, a TeamSite administrator must get involved.
· Conflict resolution/Merge may require both the DCR and the output file to be merged, which means redundant effort.
· SubmitTask generally consumes more server resources. For instance, the typical sequence “generate templated output -> submit content -> deploy content” is implemented as 5-6 tasks when SubmitTask is used (generate/error control, submit/conflict resolution, deploy/error control).
· Comments in file history (such as who approved and what transition comment they entered) cannot be controlled as easily.
2.3 Benefits of Using ExternalTask to Submit
· Comments in file history are specified exactly.
· Requires developers to avoid conflict situations before submit time.
· Generally consumes fewer server resources. The typical sequence “generate templated output -> submit content -> deploy content” can be implemented as 2 tasks (generate, submit & deploy/error control).
· Error/conflict resolution can be shared to a group rather than an individual user.
2.4 Drawbacks of Using ExternalTask to Submit
· Requires some coding (coding would be required to control comments and avoid conflicts in any case).
· Does not provide conflict resolution screen.
· Comment length may be limited by NT command line length.
Find more posts tagged with
Comments
Migrateduser
I thought I could use iwrmtaskfile and iwaddtaskfile to update the comment associated with a file. It looks like the linefeeds get stripped from the comment by iwaddtaskfile though, which makes it look really bad in file history. I may try with iwsettaskfilecomment and see what that does.
I looked at OpenAPI for this as well but I can't believe the method is this complicated (and I might have to call prepareSubmit first which is almost as complicated). I think we have to go with the ~4000 character limit and file a feature request.
public static IWFileBatch.ResultOfChange submit(IWFileSysService service,
IWDynamicArea dynamicArea,
java.lang.Object submitFileRequestInfoCollection,
long fileRelKindMask,
IWPathNamedObject.Selector fileSelector,
boolean toFileVersionMustBeVAncestorOrAbsent,
boolean overwriteConflicts,
boolean requireLocks,
IWPolicy submitPolicy,
java.lang.String submitSummaryComment,
java.lang.String submitComment,
boolean releaseLocks,
boolean includeSubmittedFilesInResultCollection,
int resultOrder)
throws IWFile.NotInAreaException,
java.rmi.RemoteException
Migrateduser
iwsettaskfilecomment causes "SYSTEM <Long Date>" to appear on each line in the file history, which is not acceptable.
copyQuealias_example_powershell.zip
Migrateduser
Well, as it turns out, a Process object in Java will remove linefeeds from all command line arguments before running the command. So to get useful comments (since my ExternalTasks are written in Java) I have to use OpenAPI or shell out to Perl to call iwsubmit. I am going to try OpenAPI, but if it turns around and calls the CLT...then I will have wated a bunch of time and will have to go back to Perl.
Migrateduser
OpenAPI too hard/lame. I will shell out to Perl.
jetform.png
Johnny
Hi there John,
Guess who
Told you perl is alot more easier with this clunky thing! :þ
John
Sydney, Australia
Migrateduser
If anyone can help with the OpenAPI, or tell me how I should pass a multi-line comment on the command line to iwsubmit, I would greatly appreciated it.
After a heck of a lot of work...
I couldn't get OpenAPI working. IWFileBatch.submit always throws an IWIllegalCollectionException. The code is below if anyone can help.
It looks like the limit on a comment is actually something more like 1023 characters, and it doesn't matter how you set the comment (whether you use iwsubmit and specify a comment, or use iwsettaskfilecomment and a SubmitTask). I imagine this is the same with OpenAPI.
For whatever reason, if I call iwsubmit from Perl, and the comment spans multiple lines such as
$comment = "hello\n";
$comment .= "John";
`iwsubmit -w "$file" "$comment"`;
Only the first line of the comment shows in the file history. I think Windows is stripping everything after the first linefeed but I was positive I had done this on other systems! To get around this issue I am using iwsettaskfilecomment to set multiple comment lines associated with the file, then a submittask (that seems to be the only way I can get a multiline comment without OpenAPI). But this wastes a lot of my 1023 characters with SYSTEM <long date>. Note that the -f option to iwsubmit does not seem to support multiline comments. Also, does Interwoven store empty transition comments (such as if a user rejects but does not enter a comment) in the task XML? I can't seem to find them.
java -classpath C:\iw-home\iwopenapi\openapi_client.jar;%CLASSPATH%;. test
It is true that test/test.txt exists in /default/main/Project/WORKAREA/teamsite
Illegal collection (or map).
com.interwoven.api.utility.IWIllegalCollectionException: Illegal collection (or
map).
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Stream
RemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:
223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
at com.interwoven.api.filesys.IWFileBatchRemoterImpl_Stub.submit(Unknown
Source)
at com.interwoven.api.filesys.IWFileBatch.submit(IWFileBatch.java:893)
at test.main(test.java:69)
import java.util.Collection;
import java.util.HashSet;
import com.interwoven.api.filesys.IWFile;
import com.interwoven.api.filesys.IWSimpleFile;
import com.interwoven.api.filesys.IWFileSysService;
import com.interwoven.api.access.IWAccessService;
import com.interwoven.api.access.IWAccessorAuthentication;
import com.interwoven.api.service.IWService;
import com.interwoven.api.filesys.IWPath;
import com.interwoven.api.filesys.IWDynamicArea;
import com.interwoven.api.filesys.IWPathNamedObject;
import com.interwoven.api.filesys.IWFileBatch;
public class test
{
public static void main(String[] args)
{
try
{
String strHostname = "hostname";
String strUser = "DOMAIN\\username";
String strPassword = "password";
String strFilePath = "/default/main/Project/WORKAREA/teamsite/test/test.txt";
String strRMI = "rmi://" + strHostname + ":1099/";
IWFileSysService fileSysService = (IWFileSysService) IWService.locate( strRMI + "IWFileSysService" );
IWAccessService accessService = (IWAccessService) IWService.locate( strRMI + "IWAccessService" );
// Use no host name in paths.
IWFileSysService.Context fileSysContext = fileSysService.getFileSysContext();
fileSysContext.setPathStyleMask( fileSysContext.getPathStyleMask() & ~( IWPath.smOutputHost ));
// Set locale
String locale = "en_US";
fileSysContext.setLocale( locale );
IWAccessorAuthentication accessorAuthentication = IWAccessorAuthentication.authenticateUserByPassword(
accessService,
strUser,
"master",
strPassword,
300 * 1000 );
fileSysService.getContext().setAccessorAuthentication( accessorAuthentication );
int intPathStyleMask = fileSysService.getFileSysContext().getPathStyleMask();
String strAreaFilePath = IWPath.extractAreaPath( intPathStyleMask, strFilePath );
IWDynamicArea objArea = (IWDynamicArea) IWPathNamedObject.lookupByPath( fileSysService, strAreaFilePath );
Collection submitCollection = new HashSet();
// Describe component to be submitted
IWFileBatch.SubmitFileRequestInfo cmpSubmitRequest = new IWFileBatch.SubmitFileRequestInfo();
cmpSubmitRequest.fileComment = "submit category";
cmpSubmitRequest.fromFile = (IWFile) IWPathNamedObject.lookupByPath( fileSysService, strFilePath );
System.err.println( "It is " + cmpSubmitRequest.fromFile.isInArea( fileSysService, objArea )
+ " that "
+ cmpSubmitRequest.fromFile.getPathRelAreaRootDir( fileSysService )
+ " exists in "
+ strAreaFilePath );
submitCollection.add( cmpSubmitRequest );
IWFileBatch.ResultOfChange submitResultCollection = IWFileBatch.submit(
fileSysService, // RMI service
objArea, // workarea area containing files
submitCollection, // collection describing files to submit
IWFile.rkmDDescendant, // directory relationships included
null, // no file selector
true, // no override
false, // not requiring locks
null, // no submit policy
"submit summary comment", // comment
"submit comment", // comment
false, // release any locks held
true, // keep successfully-submitted files in the result collection
IWFile.oNone ); // order of result collection
}
catch( Exception objException )
{
System.err.println( objException.getMessage());
objException.printStackTrace();
System.exit( 1 );
}
}
}
james1
You might have better luck using system() in Perl, e.g.:
@args
= ("iwsubmit", "-w", "foo", "bar", "line 1 \n line 2");
system(
@args
);
-- James
--
James H Koh
Interwoven Engineering
Migrateduser
Is there a way to check the OS return code and/or output using system? I've also seen open used to run commands but am not sure how to use it.
Thanks,
-John
james1
See:
http://www.perldoc.com/perl5.8.0/pod/func/system.html
-- James
--
James H Koh
Interwoven Engineering
Migrateduser
Thanks. But this seems to confirm it's not possible to capture the stderr/stdout.
Migrateduser
Well, it's a hack, but until I can get OpenAPI to work (since the ExternalTask is written in Java), I have to shell out to Perl. I have a template for a Perl script. Then in my Java CMSFile class I have a sumit method that reads the template, substitutes in the file and comment, writes the script to a temp file and executes it. There is also an ExternalTaskProcess class that needs to call this method for each file.
Now that I look at it I guess I should substitute IWHOME in the shebang line as well, not that it matters.
I think the java code should trap any errors.
Sample code should be attached.
Migrateduser
Where is my attachment?
PDF_FONTS_MAP.txt
Johnny
you can execute a command with the open function via pipes
eg open(FOO, "|tr '[a-z]' '[A-Z]'");
on the command line enter "perldoc perlfunc"
and search for "open"
you can even look at "perldoc perlipc" if you can be bothered
cheers
John
Sydney, Australia
Migrateduser
I got rid of the exception using import com.sun.java.util.collections.*; instead of java.util.Collection and java.util.HashSet. But it still doesn't submit the file, and anyway I think having to specify a username and password in an ExternalTask is unacceptable.
Migrateduser
You don't have to specify a username and password in an external task. However, you *do* have to specify a username and password to access TeamSite assets via OpenAPI. That is because an OpenAPI is a generalized, public API through which one can connect to TeamSite remotely. NOT requiring a username and password would be unacceptable to most customers for security reasons.
You may want to reconsider your decision to use an external task instead of a submit task.
Brinko Kobrin
Interwoven Staff Engineer
Migrateduser
I'm not sure that makes sense. If the process is running on the local machine as the windows SYSTEM user, or even if it wasn't, couldn't OpenAPI just use the credentials of the user, which should have the required access? I understand that would be platform specific, but I don't see how I can get much value out of OpenAPI otherwise.
james1
> If the process is running on the local machine as the windows
> SYSTEM user, or even if it wasn't, couldn't OpenAPI just use the
> credentials of the user, which should have the required access?
OpenAPI will use whatever credentials you tell it to use, when you set up your accessor object. By itself, OpenAPI will not, and cannot, magically invoke the credentials of some user that you wish it to operate as.
Hope this helps.
-- James
--
James H Koh
Interwoven Engineering
Migrateduser
Anyway I have to use an ExternalTask, since the default comments are useless and to support linefeeds in comments using iwsettaskfilecomment wastes too many characters with dates and usernames. I did find a way to start a conflict resolution task from a SubmitTask implemented as an ExternalTask but now I realize that UI is really not so great for merging DCRs (the important things) and anyway at Submit it's too late to find out about a conflict (since that's right before deployment to production and I would want to go back to generate at that point, which means re-approval...). Since it's a CGI task it can only be associated with one user, but at least I can set the user dynamically from the SubmitTask that is an ExternalTask.
Can't believe nobody has solved these problems.
Migrateduser
The more I think about this the less I understand it. No other APIs that I use force me to enter a username and password to invoke methods, even those that operate on filesystem objects. They use the credentials of the logged in user. It's like saying that if I'm logged in to a PC and I try to start a browser, the application should ask me for a username and password. I think most people would agree that this actually defeats security - the more places I have to enter or store my password, the less secure it is.
I think OpenAPI should at least have an option to use the credentials of the logged in user.
Migrateduser
As James already indicated, OpenAPI
does have
the option to use the credentials of the logged-in user. But you must supply these credentials.
As I explained previously --
OpenAPI is a generalized, public API through which one can connect to TeamSite remotely
. When you fire-up a Java VM, OpenAPI does not necessarily know who "the logged in user" is.
Brinko Kobrin
Interwoven Staff Engineer
Migrateduser
I think we are defining credentials differently. I mean the security context of the logged in user, not the username and password of a user. I understand I can establish a new security context by passing the username and password of the logged in user as text to some OpenAPI methods, but is there anyway that OpenAPI can just use the existing security context (say, of the process that is runing the Java binary)?
Migrateduser
I think we are talking about the same thing. If you look at OpenAPI, you should see a method to create a user session given a host name, port number and session string. If you are already logged in to TeamSite (through WebDesk or WebDesk Pro, for example) you can obtain the session string and -- provided that the session has not expired -- pass its value to OpenAPI.
Brinko Kobrin
Interwoven Staff Engineer
Migrateduser
No, I am talking about an ExternalTask running as the user system (though it would be nice if it could run as someone else, but that's a separate issue) as part of a workflow that needs to access the Interwoven filesystem using OpenAPI.
Migrateduser
I found another reason to use an ExternalTask. Since the submit comment is limited to about 1,000 characters, some of the information may get truncated. What I do is pass my submit method an array of strings (the comments). It takes lines (starting with the last line) from the end and inserts them at the front of the comment string it is building. If adding the next line will exceed 1,000 characters, it submits the file with the current comment, then resets the comment to the new line. It changes an extended attribute on the file so Interwoven will think there is a new version of the file, then goes to the next line in the array. Seems to work, but I haven't handled the case where an individual comment is longer than 1,000 characters.
Another thing the client wants is a comment on the file that indicates when it was deployed. Since the comments are associated with the file when it is submitted, which happens before deploy, I do the same thing change an extended attribute and call the submit method again with one item in the array, a string indicating when the deployment occurred.
One of the problems here (at least as I understand it) is that every time a file is versioned, TeamSite creates a whole copy of the file in the backing store instead of just tracking the changes. This could be bad for huge PDFs and such, since it could consume disk space too quickly. So in the Deploy script I check the file size, if it is relatively large I don't add the comment. I don't check for this in the long comments since those comments are more important (deploy date/time is set in metadata so it is visible in the UI anyway), and anyway how often are all of the comments combined going to exceed 1,000 characters?
But after all this work I realized that file history is only available to editor and above. Not sure why that would be, but I will probably have to do something custom to make it available to all users (maybe without revert). Revert shouldn't be used even by editors if they don't know how templating works, because if they revert a templated output file, it doesn't revert the DCR so their reversion will be lost when workflow regenerates. So I will probably have to write a custom revert anyway.