4

I want to extract all the promotions from the odata service using Java application. I am using the API jar as Odata4j-core and used CoreOdataJerseyConsumer to consume the service. I can access the Publications using the below code snippet

 OdataConsumer consumer=OdataJerseyConsumer.create(enddpointURI);
  client.getEntities("Publications").filter("Title eq 'Chrome Promotion'").execute().first().getProperty("Id",Integer.class).getValue();

I can view all the promotions in the browser just requesting the /odata.svc/Promotions url. But when it comes to fetch those in the java application, I am not able to get those.

UPDATED

For endpoint url I am using the odata service , that has been installed. "http://domainname/projectname/ws/odata.svc/" .
For promotions I am using the below code snippet
client.getEntities("Promotions").execute() .

The error logs ::

at java.lang.Thread.run(Thread.java:745) [na:1.7.0_55] java.lang.IllegalArgumentException: type cannot be null at org.odata4j.edm.EdmDataServices.getEdmEntitySet(EdmDataServices.java:60) at org.odata4j.internal.EdmDataServicesDecorator.getEdmEntitySet(EdmDataServicesDecorator.java:41) at org.odata4j.format.xml.AtomFeedFormatParser.parseEntry(AtomFeedFormatParser.java:367) at org.odata4j.format.xml.AtomFeedFormatParser.parseFeed(AtomFeedFormatParser.java:169) at org.odata4j.format.xml.AtomFeedFormatParser.parse(AtomFeedFormatParser.java:157) at org.odata4j.format.xml.AtomFeedFormatParser.parse(AtomFeedFormatParser.java:45) at org.odata4j.consumer.ConsumerQueryEntitiesRequest.doRequest(ConsumerQueryEntitiesRequest.java:67) at org.odata4j.consumer.ConsumerQueryEntitiesRequest.getEntries(ConsumerQueryEntitiesRequest.java:50) at org.odata4j.consumer.ConsumerQueryEntitiesRequest.execute(ConsumerQueryEntitiesRequest.java:40) at com.cde.apps.pagedirectory.PageDirectoryController.getSiteNodes(PageDirectoryController.java:75)

  • Which is the endpoint you are accesing to acquire the Promotions?. And in the case of the request of Promotions you told, which is the result from the java application? is there any error? – Raúl Escudero Dec 25 '15 at 11:13
  • Hi Raul : I have added the points in the question. – Manas.p Dec 28 '15 at 7:56
5

The OData web service is not a public API and has in fact been replaced in SDL Web 8. For that reason, I recommend against attempting to use it like this.

  • 1
    IS there any other work around for accessing the promotions from our custom solution? As Tridion also uses odata service to fetch the promotions. – Manas.p Dec 29 '15 at 5:01
  • 2
    Hi Peter, What do you mean by "OData web service is not a public API". I have used OData web service(Content delivery web service/SmartTarget web service) for querying published components as well as promotions in .Net. For using Odata service for querying published components, use case was from server on which I had deployed my application, broker database was not accessible(Due to internal network security reason). For promotions use case was there is no method available in Smart Target API which can return all the promotions for a specific page(without passing all the required triggers). – Mukesh Kumar Dec 29 '15 at 5:39
  • Public APIs are the ones that SDL provides API documentation for and explains how to use it. We work hard to make changes to them backwards-compatible and provide migration paths from previous releases. The OData web service is not one of them and so might change without notice (as it has in Web 8) and there is no emphasis on making it work in different scenarios. Managing Promotions is currently limited to the UI in the Content Manager. If you start messing with it directly through the web service, you might lose data and get unexpected behaviors. – Peter Kjaer Dec 29 '15 at 6:37
  • That said, if you are just reading the Promotions it should work fine -- but I can't give you much guidance on how to make it work in the odata4j framework as I've never used it. I would also be interested in hearing the use cases for this, as I do think that we should consider introducing a public API for this in a future version and so would like to know what you guys need. – Peter Kjaer Dec 29 '15 at 6:44
  • 1
    We require the set of promotions and the corresponding trigger related to the promotion for a particular page. So that the editor can select different promotion for a page to view different contents and subsequently can edit the page content. – Manas.p Dec 29 '15 at 8:27
3

I have been searching for a solution to your problem, but I think it is a question that must be sent to SDL, because maybe is a software fault. But maybe the odata4j library is not fully implemented, and the problem is in their side.

The main problem is that the entity model (EDM) published in the metadata of the odata service of the Promotions, doesn't match with the entity data model that the odata library expects. There is a problem with the namespaces of the entity types.

If we query for the metadata of the services published in odata with the command .../odata.svc/$metadata, something like this is obtained:

 <Schema Namespace="Tridion.ContentDelivery" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
    <EntityType Name="Promotion">
        <Key>
            <PropertyRef Name="Id"/>
        </Key>
        <Property Nullable="false" Type="Edm.String" Name="Id"/>
        <Property Nullable="true" Type="Edm.String" Name="PublicationTargetId"/>

The Namespace is "Tridion.ContentDelivery", but when the odata4j library is parsing the xml of the service, tries to match the value of the "category/term" field that is set to "Tridion.SmartTarget" to find the field types in the parsed xml. That is why the ere the "null type" of the error comes.

The two values set in the namespaces are hardcoded in the Tridion libraries, that's why I say that SDL must correct something.

In the class ODataMetaDataServiceFactory in the "cd_odata.jar" library, where the metadata of the OData Services are prepared, we have:

  public static ODataMetaDataService constructMetaDataDocument(List<ODataResourceBundleRegistrationService> bundles, List<ODataServiceOperation> serviceOperations)
  {
    ODataMetaDataService metaDataService = new ODataMetaDataService();

    MetadataSchema schema = new MetadataSchema("Tridion.ContentDelivery");
    metaDataService.getDataservice().setSchema(schema);
    for (ODataResourceBundleRegistrationService service : bundles)

And in the PromotionEntryBuilder class, of the "smarttarget_api_webservice.jar" library, where the xml of the Promotion entity, and the category is set, we have:

  protected void buildMetaInfo()
  {
    this.entry.setId(String.format("%sPromotions(Id=%s)", new Object[] { getBaseURL(), this.promotionEntity.getId() }));
    this.entry.setTitle(new ODataProperty(this.promotionEntity.getName()));
    this.entry.setAuthor(new ODataAuthor("SmartTarget"));
    this.entry.setCategory(new ODataCategory("Tridion.SmartTarget.Promotion"));
    this.entry.setUpdated(this.promotionEntity.getLastModified());
    this.entry.setEntryType(SmartTargetODataRegistrationService.PROMOTIONS);
  }

I tried to change this last class to match the category with the namespace of the metadata and I passed the previous error of the null type, but then another error comes of missing types when parsing a "datetime" field. That is why I told before that maybe the odata4j library is not totally implemented.

  • 1
    Thanx Raul. We will contact SDL for this one, also when I tried to access the components , I got the datetime parse error. Below is the error log ::::::java.lang.IllegalArgumentException: Illegal datetime format 2015-02-19T08:18:57+01:00 org.odata4j.internal.InternalUtil.parseDateTimeFromXml(InternalUtil.java:96) org.odata4j.core.OSimpleObjects.parse(OSimpleObjects.java:110) org.odata4j.core.OProperties.parseSimple(OProperties.java:116) – Manas.p Dec 28 '15 at 12:41
  • Yes, the problem with the components is the same I'm facing with the promotions. The real EdmType of the date fields is "DateTimeOffset", and the service is publishing them as "DateTime" causing the parse error. – Raúl Escudero Dec 28 '15 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.