How to add Link to Story via VersionOne REST API? - api

I'm able to create new Story via POST to /VersionOne/rest-1.v1/Data/Story with corresponding XML payload. Setting all attributes (including relational) works like a charm. However I'm unable to figure out how to add a Link asset to the Story asset.
When I try POSTing to /VersionOne/rest-1.v1/Data/Link with following XML payload:
<Asset href='/VersionOne/rest-1.v1/New/Link'>
<Attribute name='AssetType' act='set'>Link</Attribute>
<Relation name='Asset' act='set'>
<Asset href='/VersionOne/rest-1.v1/Data/Story/123' idref='Story:123'/>
</Relation>
<Attribute name='OnMenu' act='set'>true</Attribute>
<Attribute name='URL' act='set'>http://my.example.com</Attribute>
<Attribute name='Name' act='set'>My Link Title</Attribute>
</Asset>
The server however returns:
<Error href="/VersionOne/rest-1.v1/Data/Link">
<Message>Violation'Readonly'Link.AssetType</Message>
<Exception class="VersionOne.DataException">
<Message>Violation'Readonly'Link.AssetType</Message>
</Exception>
</Error>
Seems like adding links is prohibited but actually I can add Links via the standard web interface without issues.
My original idea was to create Link asset first and then update the Story with respective relational attribute pointing to that Link asset.
Any ideas anyone?
Thanks!
(I'm using JavaScript/jQuery)

My bad. The <Attribute name='AssetType' act='set'>Link</Attribute> attribute in the POST payload is obviously wrong - it is trying to set the asset's type (link) which does not make sense since I'm stating the type in URL already. It works perfectly without the attribute (as expected).

Related

LabVIEW Parsing XML String without using tools

I am creating an information displaying mini-app for a device. The response I receive from the device when I send an HTTP Get request is literally as follows:
<?xml version="1.0" encoding="iso-8859-2"?>
<root xmlns="http://www.papouch.com/xml/th2e/act">
<sns id="1" type="1" status="0" unit="0" val="25.0" w-min="" w-max="" e-min-val=" -0.3" e-max-val=" 124.0" e-min-dte="01/01/2014 13:16:44" e-max-dte="05/14/2014 10:00:43" /><sns id="2" type="2" status="0" unit="3" val="56.4" w-min="" w-max="" e-min-val=" 0.1" e-max-val=" 100.0" e-min-dte="01/27/2014 08:39:14" e-max-dte="03/04/2014 11:02:40" /><sns id="3" type="3" status="0" unit="0" val="15.7" w-min="" w-max="" e-min-val=" -21.3" e-max-val=" 85.9" e-min-dte="01/27/2014 12:21:28" e-max-dte="03/04/2014 11:29:32" /><status frm="1" location="NONAME" time="01/02/2014 7:12:00" typesens="3" /></root>
There are 3 sns elements with incrementing ids, I need to read the val attribute of the sns element with the id 1.
I tried implementing the suggested way here:Get specific XML element attributes in Labview , and shown below is my implementation, but it does not work. I tested the XPath on http://xpather.com/ and it fetches the value I need just fine.
The XPath I am using is: //root/sns[#id="1"]/#val
The result I get when I run is just nothing, no Parsing errors, no any other errors, everything seems to be okay but the String indicator is always empty, String 2 displays the HTTP response fine.
I am using (and have to use) LabVIEW 2011 SP1.
The reason why the result is empty is the wrong input of Get Node Text Content.

CRM Api FetchXml replaces characters when using like

I'm trying to call CRM Api to fetch contacts. The requirement says I can search by name using the LIKE operator.
I'm using the fetchxml below to query CRM:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name="fullname" />
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
</filter>
<filter type="and">
<condition attribute="fullname" operator="like" value="%ben%" />
</filter>
</entity>
</fetch>
The problem is: If I try with "test" for example, it works fine. But if I try to search for "ben" it doesn't. I believe the issue is related to encoding but I can't find a way to fix it. Any ideas?
Seems like encoding error in your code. Try to pass your encoded fetchxml query in the below url & test in the browser address bar. If it results the expected record(s) then it’s not platform problem.
https://<yourorg>.crm.dynamics.com/api/data/v8.2/contacts?fetchXml=encodedFetchXML
To use FetchXml, we need to format FetchXml in usable Web API service
endpoint format. We do this by storing the FetchXML in a variable and
encoding the string with the encodeURI function native to JavaScript as
below.
var encodedFetchXml = encodeURI(fetchContact);
Read more
Update:
I tested this. Both the below fetch filter worked & gave me the expected contact record in browser test.
<condition attribute="lastname" operator="like" value="%thiy%" />
<condition%20attribute="lastname"%20operator="like"%20value=%27%25thiy%25%27%20/>
Edit:
We faced this issue in our Production application today when users trying to search for %bernhard%, but we are handling in code with value="%%bbbernhard%" as a workaround.

Document id reference desn't work for impex

I have a problem with impex which contains document id reference.
From docs:
"Especially for importing partOf item values it is necessary to reference these items by means other than the usual unique column technique because partOf items often do not provide a unique key but only hold their enclosing parent as foreign key."
Items from *items.xml (only the most important parts)
<itemtype code="A" autocreate="true" generate="true" abstract="true"/>
<itemtype code="B" autocreate="true" generate="true" extends="A">
<deployment table="btable" typecode="20115" />
<attributes>
<attribute qualifier="code" type="java.lang.Integer" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false"/>
</attribute>
</attributes>
</itemtype>
<itemtype code="C" autocreate="true" generate="true">
<deployment table="ctable" typecode="20117" />
<attributes>
<attribute qualifier="code" type="java.lang.String" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false" unique="true"/>
</attribute>
<attribute qualifier="test" type="A" autocreate="true" generate="true">
<persistence type="property"/>
<modifiers optional="false" partof="true"/>
</attribute>
</attributes>
</itemtype>
Impex code:
INSERT B;code;&docIdRef
;1;docId
INSERT_UPDATE C;code[unique=true];test(&docIdRef)
;uniqueCode;docId
Error message:
cannot create C with values ItemAttributeMap[ registry: null, type: <null>, (...) due to [de.hybris.platform.servicelayer.interceptor.impl.MandatoryAttributesValidator#3b777877]:missing values for [test] in model C
When I removed 'partof' modifier from 'test' attribute (C class) everything worked fine.
I wonder how impex should looks like if i want to keep 'partof' modifier.
When you use partOf you must reference the partOf using the owner.
So it does :
INSERT B;owner(C.code);&docIdRef
;uniqueCode;docId
INSERT_UPDATE C;code[unique=true];test(&docIdRef)
;uniqueCode;docId
You don't need to assign B an identifier, you just need to reference the owner.
If you know for sure that your data is correct you can use [forceWrite=true] modifier or legacy mode to skip service layer validation.
You should also make sure that this configuration is what you really need. Setting either optional to true or partOf to false or providing default value should fix the issue as well.
Since you have mentioned partof="true" you can not assign a reference of type A. You can only create a new entity.
Check the OOTB AbstractOrder2AbstractOrderEntry relationship, they have mentioned partof="true" for AbstractOrderEntry means you can't reference any other AbstractOrderEntry to Order. You can always create new entry.
Have a look at HMC site as well
You can see here there is no + Add Entry button available here. The reciprocal can be possible.

In VersionOne REST API how does one use multiple “with” statements with multiple “Where” clauses?

With the following query:
Base-URL/rest-1.v1/Data/Epic?sel=Category.Name,Custom_RoadmapInOut&where=Number=$numbers&with=$numbers=E-05322%2CE-05280%2CE-05616%2CE-04942%2CE-04921
I am getting the following response:
<Assets total="5" pageSize="2147483647" pageStart="0">
<Asset href="End-of-Base-URL/rest-1.v1/Data/Epic/138904" id="Epic:138904">
<Attribute name="Category.Name">Business Objective</Attribute>
<Attribute name="Custom_RoadmapInOut">2</Attribute>
</Asset>
<Asset href="End-of-Base-URL/rest-1.v1/Data/Epic/139078" id="Epic:139078">
<Attribute name="Category.Name">Initiative</Attribute>
<Attribute name="Custom_RoadmapInOut">1</Attribute>
</Asset>
<Asset href="End-of-Base-URL/rest-1.v1/Data/Epic/147147" id="Epic:147147">
<Attribute name="Category.Name">Parent Story</Attribute>
<Attribute name="Custom_RoadmapInOut"/>
</Asset>
<Asset href="End-of-Base-URL/rest-1.v1/Data/Epic/148702" id="Epic:148702">
<Attribute name="Category.Name">Parent Story</Attribute>
<Attribute name="Custom_RoadmapInOut"/>
</Asset>
<Asset href="End-of-Base-URL/rest-1.v1/Data/Epic/156961" id="Epic:156961">
<Attribute name="Category.Name">Milestone</Attribute>
<Attribute name="Custom_RoadmapInOut"/>
</Asset>
</Assets>
I want to limit the results to only return those assets that have a "Category.Name" of either "Business Objective" or "Initiative" and from those types to only return the ones that have a "Custom_RoadmapInOut" set to between 1 and 99.
What do I need to add to the query to have VersionOne do the heavy lifting and return only the desired items?
I am thinking I should be able to also add:
Category.Names=$names&with=$names=Business+Objective%2CInitiative
to the query and another where part to check the Custom_RoadmapInOut but I am not sure how to do this.
Currently I am making multiple queries and then using my own code to go through the results and keep only the ones that I desire to see.
Thanks for any help that can be provided.
Doug
Multiple with values can be separated by | (pipe). If you need more details than are shown in the documentation, you can try reading the grammar.
Multiple where filter tokens must be joined by logical operators. Logical and is ; (semicolon). Logical or is | (pipe). Again, the documentation can be a little sparse so you might try reading the grammar.
If you still find yourself still needing to run multiple queries to get what you need, you may find it advantageous to convert to the query.v1 endpoint.

Problem with struts 2 and json plugin

I'm using the json plugin that comes with struts 2 (json-lib-2.1.jar) and trying to follow the website to set it up.
Here's my struts.xml
<struts>
<package name="example" extends="json-default">
<action name="AjaxRetrieveUser" class="actions.view.RetrieveUser">
<result type="json"/>
</action>
</package>
</struts>
but I get this warning:
SEVERE: Unable to find parent packages json-default
Is there something else I'm supposed to do?
Edit:
I added this method to my RetrieveUser:
public Map<String,Object> getJsonModel()
{
return jsonModel;
}
And my struts.xml looks like this:
<struts>
<package name="example" extends="json-default">
<action name="AjaxRetrieveUser" class="actions.view.RetrieveUser">
<result type="json"/>
<param name="root">jsonModel</param>
</action>
</package>
</struts>
However, I don't think the response is going from the RetrieveUser class to the javascript. I'm using firebug and no request gets sent.
I believe that net.sf.json-lib is just a toolset you can use in your Java to build up JSON-ready objects, suitable to be returned by actions such as you describe.
Probably, you need to include struts-json-plugin - make sure its version matches your struts version.
I notice also that as written, your action will attempt to return RetrieveUser, serialized. Most implementations I've done/seen specify the root object to be returned, by adding
<param name="root">jsonUser</param>
Under the tag, and define this method in RetrieveUser
public Map<String, Object> getJsonUser()
[This is mentioned in the Sruts2 doc]. Hope that helps.
[edit] I use Map - you could also use the object structures provided by json-lib instead.
Re: Your edit. Probably need to see your calling javascript. And probably I will suggest that you make sure you have both a success and an error handler. Can you debug/log to show that the method is being called in java ? Do your logs show anything ? This is usually some sort of error....