Is it possible to  perform bulk update by say utilizing both $filter and MERGE?

I need it to change a number of records with the same value but it would be nice to avoid resolving Id for each one.

Direct approach failed with an error

Query options $select, $expand, $filter, $orderby, $inlinecount, $skip, $skiptoken and $top are not supported by this request method or cannot be applied to the requested resource.

You may reproduce my call by substituting appropriate Id, actually it also should update by primary key but doesn't

url -X MERGE -H 'Content-Type: application/json;odata=verbose' -H 'Accept: application/atom+xml' -i 'http://terapp-t.hq.eximb.com/0/ServiceModel/EntityDataService.svc/Accou? eq '\''648dbb58-2aea-578d-e053-2413a8c01794'\' --data '{Name: '\''Other name'\''}'

Was my syntax incorrect or the whole idea?

 

Like 0

Like

1 comments

Hello,

Unfortunately, one http request can contains only one CRUD operation for Odata, unless using batch.

In order to update the record by primary key, please use the following syntax:

'http://terapp-t.hq.eximb.com/0/ServiceModel/EntityDataService.svc/AccountCollection(guid'648dbb58-2aea-578d-e053-2413a8c01794')'







 

Show all comments
package cherniak.bpmonline.com;
import java.io.OutputStream;
import java.net.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Attr;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* OData insert request for bpmonline
*
*/
public class App
{
    private static final String SERVICE_URL = "http://int-                web/Amdocs_T/0/ServiceModel/EntityDataService.svc/";
    private static final String AUTH_URL = "http://int-web/Amdocs_T/ServiceModel/AuthService.svc/Login";
    private static final String DS = "http://schemas.microsoft.com/ado/2007/08/dataservices";
    private static final String DSMD = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
    private static final String ATOM = "http://www.w3.org/2005/Atom";
    public static void main( String[] args ) throws Exception
    {
        CookieManager msCookieManager = new CookieManager();
        CookieHandler.setDefault(msCookieManager);
        if(GetAuthCookie("Supervisor", "Supervisor")) {
            CreateBpmEntityByOdataHttpExample(msCookieManager);
        }
    }
    public static boolean GetAuthCookie(String login, String password) {
        try{
            URL urlAuth = new URL(AUTH_URL);
            HttpURLConnection connection1Auth = (HttpURLConnection) urlAuth.openConnection();
            connection1Auth.setDoOutput(true);
            connection1Auth.setRequestMethod("POST");
            connection1Auth.setRequestProperty("Content-Type","application/json");
            String authJson = String.format("{\"UserName\": \"%s\", \"UserPassword\":\"%s\"}", login, password);
            byte[] outputBytes = authJson.getBytes("UTF-8");
            OutputStream os = connection1Auth.getOutputStream();
            os.write(outputBytes);
            os.close();
            int responseCode = connection1Auth.getResponseCode();
            return responseCode == 200;
        } catch (Exception e) {
            return false;
        }
    }
    public static void CreateBpmEntityByOdataHttpExample(CookieManager manager) {
        try{
            //Create xml document
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            Element entry = doc.createElement("entry");
            Attr attrAtom = doc.createAttribute("xmlns");
            attrAtom.setValue(ATOM);
            entry.setAttributeNode(attrAtom);
            doc.appendChild(entry);
 
            Element content = doc.createElement("content");
            Attr attrType = doc.createAttribute("type");
            attrType.setValue("application/xml");
            content.setAttributeNode(attrType);
            entry.appendChild(content);
 
            Element properties = doc.createElement("properties");
            Attr attrMetadata = doc.createAttribute("xmlns");
            attrMetadata.setValue(DSMD);
            properties.setAttributeNode(attrMetadata);
            content.appendChild(properties);
 
            //Set Name of Contact
            Element name = doc.createElement("Name");
            Attr attrProp = doc.createAttribute("xmlns");
            attrProp.setValue(DS);
            name.setAttributeNode(attrProp);
            name.appendChild(doc.createTextNode("Test Person"));
            properties.appendChild(name);
 
            //Set Dear of Contact
            Element dear = doc.createElement("Dear");
            Attr attrOppo = doc.createAttribute("xmlns");
            attrOppo.setValue(DS);
            dear.setAttributeNode(attrOppo);
            dear.appendChild(doc.createTextNode("Mister"));
            properties.appendChild(dear);
 
            doc.setXmlStandalone(true);
 
            //Send insert request
            URL url = new URL(SERVICE_URL + "ContactCollection/");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "application/atom+xml");
            connection.setRequestProperty("Content-Type","application/atom+xml;type=entry");
 
            //Add BPMCSRF
            for(HttpCookie cookie : manager.getCookieStore().getCookies()) {
                if(cookie.getName().equals("BPMCSRF")) {
                    connection.setRequestProperty("BPMCSRF", cookie.getValue());
                }
            }
            OutputStream os = connection.getOutputStream();
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.transform(new DOMSource(doc), new StreamResult(os));
            os.close();
            int responseCode = connection.getResponseCode();
            System.out.println(responseCode);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

 

Like 0

Like

Share

0 comments
Show all comments

we've created folders for subset of contacts.  I want to pull those contacts via ODATA.  anyway to filter contacts using a specific folder?

 

I.e. create an ODATA filter like filter=folder eq "VIP Contacts"

Like 0

Like

1 comments

Dear Brian,

Instead of ContactCollection, you can use ContactInFolderCollection to retrieve the folder to which the user belongs. For example (GET ServiceModel/EntityDataService.svc/ContactCollection(guid'6f586c21-4b51-42c4-a370-deec97d28c12')/ContactInFolderCollectionByContact)



ContactFolder is the object that contains all folders in case you need to get the particular folder. 

Lisa

Show all comments

Hello,

Is it possible to use SQLServer Integration Services to pull data from BPMOnline? I tried setting up a connection via the odata connection in SSIS but the connection fails. Screenshot below. Any suggestions to resolve this are highly appreciated. Thank you.

Like 0

Like

5 comments
Best reply

Dear Allen,

The error "401 Unauthorized" usually indicates, that credentials you have inserted are invalid.

Please try to run the following URL in the browser, where Supervisor:Supervisor are your login and password:

https://Supervisor:Supervisor@026218-crm-bundle.bpmonline.com/0/ServiceModel/EntityDataService.svc

If it does let you in, than check the credentials.

You can also catch the request using Telerik Fiddler application and use its parameters to set up SQLServer Integration Services connection.

Regards,

Anastasia

Hello Allen,

Please try to establish connection through EntityDataService.svc. Modify the URL in the following way:

https://026218-crm-bundle.bpmonline.com/0/ServiceModel/EntityDataServic…

Hope you find it helpful.

Regards,

Anastasia

Thank you for the suggestion. Unfortunately I still get a very similar error as the previous one. Screenshot attached.

Dear Allen,

The error "401 Unauthorized" usually indicates, that credentials you have inserted are invalid.

Please try to run the following URL in the browser, where Supervisor:Supervisor are your login and password:

https://Supervisor:Supervisor@026218-crm-bundle.bpmonline.com/0/ServiceModel/EntityDataService.svc

If it does let you in, than check the credentials.

You can also catch the request using Telerik Fiddler application and use its parameters to set up SQLServer Integration Services connection.

Regards,

Anastasia

I tried the Supervisor login and it did not complain about the invalid login. This time it shows a message indicating "Too many automatic redirections were attempted"

Dear Allen,

The issue is caused by distributed licenses. Supervisor user does not have a license, therefore, every time you try to login into system, it redirects you to the license manager page.

Please use your credentials of user "Allen Dsouza" in the connection settings. On the other hand, you can distribute licenses for the Supervisor user. In this case you will successfully connect under Supervisor credentials.

Regards, 

Anastasia

Show all comments
Question

I was wondering where I can find the JSON format or record layout for an odata record in Json format; creating a contact record for example.  Can the odata service describe the format?

Thanks 

Like 0

Like

2 comments

It seems the basic format is simple, I jump the gun

  { 

                'Name': 'Test User',

                'Dear': 'TU',

                'Email': 'Tester@TestsMarketNetServices.com',

                'Phone': '6168477992',

                'Notes': 'Testing 123' 

    }

Additional question: Can you nest relationships with the same document, like activities or do they have to be created separately?

John Adkins,

Yes, you have to create them separately. There is not way to nest relationships.

Regards,

Anastasia

Show all comments

Hi all,

2 days ago I posted asking for odata query with relationship: https://community.bpmonline.com/questions/odata-joins

I solved this issue and I posted a solution for that.

I come back because I made working querys with 1/1 relationship but not 1/n for example the idea is to get all the contacts for a particular account:

https://URL/0/ServiceModel/EntityDataService.svc/AccountCollection(guid…

I get the attached error.

Do i have an error with the relationship names? It's possible to do in bpm'online ?

Kind regards

File attachments
Like 0

Like

3 comments

Dear Uriel,

You can achieve such task by referring to the contact collection, filtering the results by Account Id. 

The request line should look like this:

// GET <BPMonline application address>/0/ServiceModel/EntityDataService.svc/ContactCollection?$filter=AccountId eq guid'00000000-0000-0000-0000-000000000000'

You can find more filter usage here:

https://academy.bpmonline.com/documents/technic-sdk/7-8/working-bpmonli…

Also, in case you use $expand in your requests, please, take into account, that in this case OData is limited to not more than13 objects to return (see info box).

https://msdn.microsoft.com/en-us/library/gg309461(v=crm.7).aspx#BKMK_ex…

Regards,

Anastasia

Anastasia, how are you?

thanks for the comment.

We need something different. The query would be from 1 to N, for example from an account bring all contacts as a collection and for each contact for example bring us all the addresses.

Thinking of an XML response we should have something like this:

 



<?xml version="1.0" encoding="UTF-8"?>

<Response>

       <Account>

              <Name>Coca Cola</Name>

              <Contacts>

                     <Contact>

                            <Name>john</Name>

                            <Addresses>

                                   <Address>234 street</Address>

                   <Address>2234 street</Address>

                               </Addresses>

                        </Contact>

                     <Contact>

                            <Name>Peter</Name>

                <Addresses>

                                   <Address>234 street</Address>

                               </Addresses>

                        </Contact>

                     <Contact>

                            <Name>Caroline</Name>

                        </Contact>

                 </Contacts>

          </Account>

   </Response>



thank you very much.

Kind regards

Uriel,

Unfortunately, possibility to expand collection is not yet implemented in the system. However, please feel free to use the above mentioned approach, as a workaround. 

Regards, 

Anastasia

Show all comments

Hi All!

We need to make the following query in OData using Http request.

 

SQL query:

 

select A.FieldZ, B.FieldX

from A inner join B on A.FieldA = B.FieldA

Basically the idea is to get data between relationships por example in one request to get an account including their contacts

if it is possible?

 

Thank you

Regards

 

Like 0

Like

1 comments

Good morning,

I'm trying to follow the sample proposed on https://academy.bpmonline.com/documents/technic-sdk/7-10/working-bpmonline-objects-over-odata-protocol-wcf-client

But getting error when try to add the Web reference using the URL, in my case http://10.150.17.28:83/0/ServiceModel/EntityDataService.svc/, it says there not web services availables on this url, what could be missing?, it happens on this bpmonline 7.6 implementation and also on a 7.10 implementation.

The proyect I created to try this is a WCF Service Library, it's ok?

Thanks in advance

 

Like

7 comments

It's ok. Hovewer, it's not recommended to use WCF in bpm'online. It's much better to use web http requests instead. I understand that it looks like WCF is more comfortable to use because of the proxy class, but it will generate a lot of difficulties in the future. 

Please check the attached file. It shows how to create an OData integration via web http requests correctly. The only thing that it missed is CSRF cookie. Please add it on your own.

https://academy.bpmonline.com/documents/technic-sdk/7-10/protection-csr…

odatawebhttprequestsupd.docx

 

The odatawebhttprequestsupd.docx example is written using fiddler 

http://www.telerik.com/fiddler

Thanks Mark, I will try

Good morning Mark,

I did some test using your tutorial and Fiddler (very good, thanks!), but now, How can I create a WS to an external app could insert data or query data to/from bpmonline using EntityDataService.svc and AuthService.svc?

Is there another tuto to this stuff?, could you help me please?

Thanks in advance,

Best regards,

Dear Julio,

 

You can achieve your task by using the OData intagration. You may find the tutorial here - https://academy.bpmonline.com/documents/technic-sdk/7-10/odata.

 

Lisa

Thanks Lisa, I will try, what kind of proyect I must to start on Visual studio? console?, Web? the module where I must create and insert the code explained in the academy, what kind of module must I add to the proyect?

I did it and get a lot of comiplation errors, I'm using, in this case VS 2015

The sample provided in the academy assumes a lot of steps I didn't know,

Can I work with VS 2017? I understand it doesn't supports OData at this time.

Thanks in advance

Dear Julio,

You can use any type of project, but we recommend to use 'Console' one.

The errors occur because you have to insert a piece of code into the brackets. Please see screenshot below:

http://prntscr.com/fpi5dj

Regarding using VS 2017, I have clarified this issue with our platform team. There is no reasons to consider that it doesn't support Odata. 

Best regards,

Diana Adams

Show all comments

I'm creating an integration to bpm online. So far I have the authentication working! 

I received the cookies and added them to the get request. But I receive a 500 internal server error. This is the url I'm calling:

https://acuity.bpmonline.com/ServiceModel/EntityDataService.svc/ContactCollection?selectId,Name 

When I look at the response in webview I see the following:

We guarantee your confidentiality and anonymity.

Date: 5/19/2017 4:00:40 PM
Date (UTC): 5/19/2017 1:00:40 PM
User:
SessionID: vfakqfdo0pu5kiq4hhfqlzgx

Is there anyone who had the same problem, or can see what I'm doing wrong. 

I've added a fiddler screenshot of the request in the attachments.

 

File attachments

Like

1 comments

Dear Stefanie,

The issue is connected to the URL you are using to obtain the data. You are missing the configuration indication. Please see the modified URL below, I have added "0" before ServiceModel.

https://acuity.bpmonline.com/0/ServiceModel/EntityDataService.svc/ContactCollection?selectId,Name 

Feel free to use this URL and proceed with your work and system functionality.

Show all comments

Hi,

Can anybody give an example of how to upload attachments via OData?

Like

11 comments

Dear Alexander,

Please find more information and documentation about O'Data on the official website http://www.odata.org/ as we do not have such examples.

Regards,

Lily

Hi,

Here is an example how to create Activity and upload attachment to it:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Services.Client;
using System.Net;
using ODataProxyClient.ODataProxyClient;//Reference to EntityDataService.svc proxy

namespace ODataProxyClient
{
	class Program
	{
		//Specify your website Uri here
		private const string baseUri = "https://yoursite.bpmonline.com";
		private static Uri serverUri = new Uri(baseUri + @"/0/ServiceModel/EntityDataService.svc/");

		static void Main(string[] args)
		{
			CreateActivityWithAttachment();
		}

		static void OnSendingRequestCookie(object sender, SendingRequestEventArgs e)
		{
			Authentification.TryLogin("Supervisor", "Supervisor", baseUri);
			var req = e.Request as HttpWebRequest;
			req.CookieContainer = Authentification.AuthCookie;
			e.Request = req;
		}

		public static void CreateActivityWithAttachment()
		{
			Guid activityId = Guid.NewGuid();
			//Create application context
			var context = new BPMonline(serverUri);

			DataServiceRequestArgs _args = new DataServiceRequestArgs();
			//Define content type
			_args.ContentType = "application/octet-stream";

			//Read file from file system
			byte[] bytes = System.IO.File.ReadAllBytes(@"C:\Activity.csv");

			using (var fs = new MemoryStream(bytes))
			{
				//Create new activity. Remember to specify all required fields
				var activity = new Activity()
				{
					Id = activityId,
					Title = "Test activity with attachment",
					TypeId = new Guid("FBE0ACDC-CFC0-DF11-B00F-001D60E938C6"),
					StatusId = new Guid("384D4B84-58E6-DF11-971B-001D60E938C6"),
					AuthorId = new Guid("410006E1-CA4E-4502-A9EC-E54D922D2C00"),
					OwnerId = new Guid("410006E1-CA4E-4502-A9EC-E54D922D2C00"),
					StartDate = DateTime.Now,
					DueDate = DateTime.Now,
					ActivityCategoryId = new Guid("F51C4643-58E6-DF11-971B-001D60E938C6"),
					PriorityId = new Guid("AB96FA02-7FE6-DF11-971B-001D60E938C6")
				};
				//Create new activity attachment
				//Remember to specify filename with extension
				ActivityFile NewFile = new ActivityFile()
				{
					Id = Guid.NewGuid(),
					Name = "Activity.csv",//File name with extension
					Size = (int)fs.Length,
					TypeId = new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"),//Attachment type - File
					Uploaded = true
				};
				//Define method for authentication
				context.SendingRequest += new EventHandler<SendingRequestEventArgs>(OnSendingRequestCookie);
				//Add created activity to collection
				context.AddToActivityCollection(activity);
				//Add new activity file to collection
				context.AddToActivityFileCollection(NewFile);
				//Link file with activity
				context.SetLink(NewFile, "Activity", activity);
				//Save changes
				DataServiceResponse responces = context.SaveChanges();
				//Write file stream to activity file
				context.SetSaveStream(NewFile, "Data", fs, true, _args);
				//Save changes
				context.SaveChanges();
			}
		}
	}
}

 

The same example via the HttpWebRequest

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Xml;
using System.Xml.Linq; 

namespace ConsoleApplication1
{
    class Program
    {
        // String of address bpm’online OData servise.
        private const string serverUri = "https://0424747-sales-enterprise-demo.bpmonline.com/0/ServiceModel/EntityDataService.svc/";
        private const string authServiceUtri = "https://0424747-sales-enterprise-demo.bpmonline.com/ServiceModel/AuthService.svc/Login";

        // Links to XML name spaces.
        private static readonly XNamespace ds = "http://schemas.microsoft.com/ado/2007/08/dataservices";
        private static readonly XNamespace dsmd = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
        private static readonly XNamespace atom = "http://www.w3.org/2005/Atom";

        private static readonly Guid FileTypeId = new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"); 

        static void Main(string[] args)
        {
            var file = ReadFile("z:/2SupportLine/chrome.png");
            var id = CreateBpmEntityByOdataHttpExample();
            TransferImage(id, "Data", file);

        }

        public static Guid CreateBpmEntityByOdataHttpExample()
        {
            Guid id = Guid.NewGuid();
            // Creating a xml message containing data on the created object.
            var content = new XElement(dsmd + "properties",
                          new XElement(ds + "ContactId", new Guid("410006e1-ca4e-4502-a9ec-e54d922d2c00")),//supervisor contact Id
                          new XElement(ds + "Id", id.ToString()),
                          new XElement(ds + "TypeId", FileTypeId.ToString()),
                          new XElement(ds + "Name", "test1.png")
                          );
            var entry = new XElement(atom + "entry",
                        new XElement(atom + "content",
                        new XAttribute("type", "application/xml"), content));
            Console.WriteLine(entry.ToString());
            // Creating a request to the service which will add a new object to the contacts collection.
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "ContactFileCollection/");
            request.Credentials = new NetworkCredential("Supervisor", "Supervisor");
            request.Method = "POST";
            request.Accept = "application/atom+xml";
            request.ContentType = "application/atom+xml;type=entry";
            // Recording the xml message to the request stream.
            using (var writer = XmlWriter.Create(request.GetRequestStream()))
            {
                entry.WriteTo(writer);
            }
            // Receiving a response from the service regarding the operation implementation result.
            using (WebResponse response = request.GetResponse())
            {
                if (((HttpWebResponse)response).StatusCode == HttpStatusCode.Created)
                {
                    // Processing the operation implementation result.
                }
            }
            return id;
        }

        public static void TransferImage(Guid fileRecordId, string columnName, byte[] file)
        {
            // Creating a request to the service which will add a new object to the contacts collection.
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "ContactFileCollection(guid'" + fileRecordId.ToString() + "')/" + columnName);
            request.Credentials = new NetworkCredential("Supervisor", "Supervisor");
            request.Method = "PUT";
            request.Accept = "application/octet-stream,application/json;odata=verbose";
            request.ContentType = "multipart/form-data;boundary=+++++";
            // Recording the xml message to the request stream.
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(file, 0, file.Length);
            }
            // Receiving a response from the service regarding the operation implementation result.
            using (WebResponse response = request.GetResponse())
            {
                if (((HttpWebResponse)response).StatusCode == HttpStatusCode.Created)
                {
                    // Processing the operation implementation result.
                }
            }
        }

        public static byte[] ReadFile(string filePath)
        {
            byte[] imageArray = System.IO.File.ReadAllBytes(filePath);
            return imageArray;
        }
    }
}

 

Mark Bailey,

I know this is a bit of an old post but I'm currently trying to implement your HttpWebRequest example. Do you know if this is still the correct way to implement the upload or has something changed? When I run this, I get a StatusCode of "NoContent" (not "Created") - with no error message or anything. Any help would be appreciated.

Aron Hoekstra,

There are two methods in the example 

CreateBpmEntityByOdataHttpExample 
and 
TransferImage

Which one is not working? Does the system create a new empty file?

Additionally, please check if the path to the file is correct 

var file = ReadFile("z:/2SupportLine/chrome.png");

Mark Bailey,

It is the TransferImage portion which is causing a problem. I have modified your code a bit to fit my use case but the end result is yes I get a new attachment record, but I can't click to actually download the file. I basically get a 404. Yes I have confirmed I am reading the file correctly and getting the byte array into the 'file' variable.

Aron Hoekstra,

The fact that you receive the 404 exception means that you didn't load the attachment in the "TransferImage" method.

Please try to run my code instead the one that you modified. Please check it if works without the moifications. Please sent me the code that you ran. Additionally, please catch the request that you send in the TransferImage method with fiddler and let me check it.

Mark Bailey,

I went back to your example and it worked.. So I went back to my code and realized that I hadn't assigned the TypeId field as you do in your example. I didn't know that was a required field - but apparently it is. My code is now working - thanks for your help!

Mark Bailey,

This is an old post, but I am testing your code to create attachments in 7.13. I am using your sample code as-is with the exception of changing URLs etc.

The ContactFile record is created file in the CreateBpmEnityByODataHttpExample method, however, when the TransferImage method runs I get a 405 "method not allowed" error. I've tried PATCH and MERGE instead of PUT with the same results.

Do you happen to know if this should still work in 7.13? Maybe I am missing something? 

Thanks,

Ryan

bsegers@goism.com,

Ryan Farley,

Unfortunately, there is no such possibility on current system version, Please feel free to use basic functionality for working with files. Take a look at FileServices and FileRepository schemas in the system configuration. There you can find methods for upload/download of file and use it in your development.

Regards,

Anastasia

In our implementation, it worked fine using the HttpWebRequest form, but now it is no longer working and returns the following error.

'The remote server returned an error: (400) Incorrect Request.'

 

UPDATE: My problem is when I try to upload a .docx or .xlsx type file, and it fails to upload, when it is a PNG or PDF it works normally.

 

Show all comments