It's all about the answers!

Ask a question

Is a file artifact in RAM given a URL?


Janette Wong (711311) | asked Mar 22 '12, 3:34 p.m.
Hi,

If I upload a file artifact (e.g. a Word doc) with an asset, can I programmatically by using the RAM API retrieve a URL/link which points to the file?

In the Class Artifact javadoc, there is no getURI() or something like that. There is a getPath(), but path is not the same as URI. I also looked into RAMArtifact class and LocalFileArtifact class and also could not find a getURI() type of method.

Thanks!

13 answers



permanent link
Sheehan Anderson (1.2k4) | answered Mar 22 '12, 3:55 p.m.
JAZZ DEVELOPER
The format is

https://<server>/ram/artifact/<asset>/<version>/<file>

For example
https://example.com/ram/artifact/5FBDF7F7-EE59-B73D-E7FE-DB43EF45B91F/1.0/myFolder/myFile.doc

permanent link
Rich Kulp (3.6k38) | answered Mar 23 '12, 10:36 a.m.
FORUM MODERATOR / JAZZ DEVELOPER
Also if you are doing this through a program instead of from a browser then you would probably want to use the ram.ws content path because that takes Basic authentication instead of Form authentication. Basic is easier to do when writing code.

i.e.

https://example.com/ram.ws/artifact/.....

permanent link
Janette Wong (711311) | answered Mar 23 '12, 11:41 a.m.
Also if you are doing this through a program instead of from a browser then you would probably want to use the ram.ws content path because that takes Basic authentication instead of Form authentication. Basic is easier to do when writing code.

i.e.

https://example.com/ram.ws/artifact/.....


Thanks to both of you who replied.. I need to ask a couple more questions:

1) Is there a method or API where I can get the URL value directly? You showed me the format/syntax and gave me an example, but am I supposed to call a number of methods to retrieve the components of the URL and then put it together? e.g. the <server> component, the GUID component, the version, etc.

2) I don't understand the significance of the authentication part. Are you referring to the case where a user who is *not* logged in and when the user clicks on the link to the file, the user will be requested to authenticate and therefore there is a difference between Basic authentication and Form authentication? What do I have to do in my code to handle security? Isn't that taken care of by WAS underneath?

Thanks

permanent link
Rich Kulp (3.6k38) | answered Mar 23 '12, 12:32 p.m.
FORUM MODERATOR / JAZZ DEVELOPER
(2) first.

This is only if the asset is not visible to anonymous users (i.e. you are not logged in). In that case authentication would be required to see if you have access to the artifact.

If you are using a browser then don't worry about any of this. The browser would bring up the login screen and you as a user would just login from there. What I'm talking about here is when you are writing a program to get the data. In that case the program needs to handle the login.

If you were going to the ram (web) side then Form authentication is required. If you are writing a program to access the data (not using a browser) then you would need to write code to handle the Form authentication (returning the userid and password in just the correct format) to login and get access to the artifact.

If instead you went to the ram.ws side Basic authentication is used. Practically all of the standard HTTP clients can handle Basic authentication. All you do is before the Get transaction you supply to the HTTP client the userid and password. In that case the HTTP client will send that information along and do the login for you.

permanent link
Rich Kulp (3.6k38) | answered Mar 23 '12, 1:17 p.m.
FORUM MODERATOR / JAZZ DEVELOPER
(1)

If you are using RAM API, then you can an input stream from RAMArtifact using the downloadContents() method.

If you wanted to use only REST access (i.e. just HTTP get's) then you can use the OSLC REST calls. Before 7.5.1.1 there is only version one format of OSLC. With 7.5.1.1 there is a version 2 format, but version one will still be supported.

For more OSLC V1 detail see:
https://jazz.net/wiki/bin/view/Main/RamRestApiMain

But for artifact specific use:

https://host/ram.ws/oslc/assets/guid/version

And set into the header param: "Accept: application/xml". This will then return the asset in xml OSCL V1 format.

The artifact details are listed in here like this: Use the bold rdf:resource as the URL for the contents of the artifact. It is relative to the https://.../ that you used above.


<oslc_asset:artifact oslc_asset:etag="1320282464960" rdf:about="oslc/assets/3E8783A1-A873-9710-2BBB-F520535B9ED2/1.0/artifacts/ratlc_values001.gif">
<dc:title>ratlc_values001.gif</dc:title>
<oslc_asset:size>6895</oslc_asset:size>
<ram:reference>
<value>ratlc_values001.gif</value>
</ram:reference>
<oslc_asset:mimeType>image/gif</oslc_asset:mimeType>
<oslc_asset:content rdf:resource="oslc/assets/3E8783A1-A873-9710-2BBB-F520535B9ED2/1.0/artifactContents/ratlc_values001.gif"/>
<dc:modified>2011-11-02T21:07:44.960-04:00</dc:modified>
</oslc_asset:artifact>

permanent link
Janette Wong (711311) | answered Mar 23 '12, 1:44 p.m.
(1)

If you are using RAM API, then you can an input stream from RAMArtifact using the downloadContents() method.

If you wanted to use only REST access (i.e. just HTTP get's) then you can use the OSLC REST calls. Before 7.5.1.1 there is only version one format of OSLC. With 7.5.1.1 there is a version 2 format, but version one will still be supported.

For more OSLC V1 detail see:
https://jazz.net/wiki/bin/view/Main/RamRestApiMain

But for artifact specific use:

https://host/ram.ws/oslc/assets/guid/version

And set into the header param: "Accept: application/xml". This will then return the asset in xml OSCL V1 format.

The artifact details are listed in here like this: Use the bold rdf:resource as the URL for the contents of the artifact. It is relative to the https://.../ that you used above.


<oslc_asset>
<dc>ratlc_values001.gif</dc>
<oslc_asset>6895</oslc_asset>
<ram>
<value>ratlc_values001.gif</value>
</ram>
<oslc_asset>image/gif</oslc_asset>
<oslc_asset>
<dc>2011-11-02T21:07:44.960-04:00</dc>
</oslc_asset>


Let's say I want to use the RAM API. Are you saying I should call downloadContents() and parse the results to get at the rdf:resource value and stick the "https://host/ram.ws" in front of it to form the URL?

Thanks

permanent link
Derek Baron (6632) | answered Mar 23 '12, 5:19 p.m.
JAZZ DEVELOPER
Hi Janette, I'd like to recommend you disclose the full scenario you're trying to achieve, I think this will help Rich provide the best fitting solution.

Rich, she wants to create a custom policy (she already has done some basic policy writing).

This policy will be used to populate one or more asset attributes with a URL link to specific content within the asset. e.g.: An asset attribute might be called "SOA spec" and the value of the attribute would be a URL directly to a file within the asset.

The name of the file won't be known ahead of time, however, there will be a naming convention for such files so the Policy can search for content using a regular expression.

So the inputs for the asset might be things like:
1. name of attribute to populate
2. regular expression to use when searching content for the file

Anyway, the point is that she's struggling to figure out how to get a URL reference to the content within the asset.

I'm hoping it'll be easier since the policy will be running within the asset session already?

Hope this helps!

P.S. She is also aware of the "featured content" feature

permanent link
Janette Wong (711311) | answered Mar 26 '12, 10:40 a.m.
Hi Janette, I'd like to recommend you disclose the full scenario you're trying to achieve, I think this will help Rich provide the best fitting solution.

Rich, she wants to create a custom policy (she already has done some basic policy writing).

This policy will be used to populate one or more asset attributes with a URL link to specific content within the asset. e.g.: An asset attribute might be called "SOA spec" and the value of the attribute would be a URL directly to a file within the asset.

The name of the file won't be known ahead of time, however, there will be a naming convention for such files so the Policy can search for content using a regular expression.

So the inputs for the asset might be things like:
1. name of attribute to populate
2. regular expression to use when searching content for the file

Anyway, the point is that she's struggling to figure out how to get a URL reference to the content within the asset.

I'm hoping it'll be easier since the policy will be running within the asset session already?

Hope this helps!

P.S. She is also aware of the "featured content" feature


Thanks Derek... Rick, indeed, the scenario is that I want to populate an attribute of type Link with the URL of a specification document which the user uploaded as part of an asset. i.e. When the user submits/creates the asset, she uploads an artifact (which is actually a specification document) with the asset. I want to be able to click on that Link attribute and open up the specification document.

Let's make the situation a bit simpler -- let's assume the specification document will always have the string 'ServiceSpec' as part of its file name. From all you've told me above, it seems:

1. There is no direct API to get at the URL of the artifact
2. I can use the downloadContent() method, but will have to parse the stream to retrieve a portion of the URL
3. Then I have to add in the remaining portion(s) of the URL to form the whole URL and populate the Link attribute with the URL which I formulated.

Correct?

Also, since there is no formal API to retrieve the URL, does it mean the URL of an artifact is really 'internal' and that it is subjected to change in the future? If I populate my Link attribute with the artifact's URL, will my link be broken in some future release of RAM?

Thanks.

permanent link
Rich Kulp (3.6k38) | answered Mar 26 '12, 12:08 p.m.
FORUM MODERATOR / JAZZ DEVELOPER
Ok, now that I know what you are trying to do.

First, downloadContents() would never give a URL. It would actually download the physical bits of the content, such as the .doc file itself. I wasn't sure what you wanted the URL for. I had assumed you were trying to get the contents of the document, not to give a URL to someone else.

Second, there is no API to give you or to create a URL to an artifact.

The artifact URL format hasn't changed since RAM was created. But it isn't an API link either. We have no intention of changing at this time.

Also from your last post, you are talking about someone that is accessing this through a Web browser. In that case my discussion about ram vs. ram.ws means you should be using ram. You would use ram.ws in the case that the accessor would be a program and not someone clicking on a link.

To create such a link you need to know the base URL (e.g. "https://server/ram") and then you would need to look through the RAMArtifacts to find the one(s) you are interested in and then create the URL using this pattern:

https://server/ram/artifact/guid/version/path/filename

path may be empty (i.e. the file is at the root of the asset) in which case you would not include the path/ in the url.

permanent link
Janette Wong (711311) | answered Apr 05 '12, 3:12 p.m.
Ok, now that I know what you are trying to do.

First, downloadContents() would never give a URL. It would actually download the physical bits of the content, such as the .doc file itself. I wasn't sure what you wanted the URL for. I had assumed you were trying to get the contents of the document, not to give a URL to someone else.

Second, there is no API to give you or to create a URL to an artifact.

The artifact URL format hasn't changed since RAM was created. But it isn't an API link either. We have no intention of changing at this time.

Also from your last post, you are talking about someone that is accessing this through a Web browser. In that case my discussion about ram vs. ram.ws means you should be using ram. You would use ram.ws in the case that the accessor would be a program and not someone clicking on a link.

To create such a link you need to know the base URL (e.g. "https://server/ram") and then you would need to look through the RAMArtifacts to find the one(s) you are interested in and then create the URL using this pattern:

https://server/ram/artifact/guid/version/path/filename

path may be empty (i.e. the file is at the root of the asset) in which case you would not include the path/ in the url.

Hi (Rich),

Based on your reply, I wrote a custom policy to retrieve the URL of my artifact (which is actually a specification document). That little chunk of code seems ok. Then, I have the code below to actually set an attribute of Link datatype (the attribute is called "Service Specification"):

private void setServiceSpecLink(RAMAsset serviceAsset, String ssDocURL, Result status){
// look up the Service Spec attribute and set the link

String[] value = new String;
String[] afterValue = new String;
AssetAttribute ssd = serviceAsset.getAssetAttribute("Service Specification");
value = ssDocURL;
status.setMessage("Before calling ssd.setValues(), value = "+value);
ssd.setValues(value);
afterValue = ssd.getValues();
status.setMessage("After calling ssd.setValues(), afterValue = "+afterValue);
}

I added the 'afterValue' just so that I can display a message to see what value I set into the 'ssd' attribute.

I ran the policy and got no exception. However, the attribute 'Service Specification' is not displayed -- I can't see it, although my URL looks ok. In fact, if I cut and paste that URL directly (manually) into the Service Specification attribute, it is fine. Do you have any idea why my Service Specification attribute is not displaying?

Also, is there a way to set the Label for the Link attribute? I can't find a setLabel() method.

Thanks

Your answer


Register or to post your answer.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.