Вопрос

Доброго дня.

Необходима интеграция с корзиной сайта, откуда заказы валятся на Magento 1.

Настроено API: есть URL-адрес для подключения с Magento, user и login.

Не понятна сама настройка веб-сервиса в bpm'online. Сталкивался ли кто-то с данной интеграцией, либо может кто-то теоретически понимает это?

У меня такой же вопрос

2 комментария

Дополнение. Подключение посредством SOAP.

Добрый день!

Не уверен, что есть какой-то готовый коннектор (по крайней мере на маркете я ничего не нашёл), но в любом случае, можно запилить свою интеграцию через свой SOAP сервис. Правда для этого нужны компетенции и в bpm и в api magento.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Коллеги, приветствую!

Следующая ситуация возникла - с внешнего веб-сервиса прилетает ответ на bpmonline. В логах внешнего веб-сервиса видим, что ответ отправляется с данными, однако когда он доходит до bpmonline - данных нет, http код равен 0 и тело ответа пустое. Типы данных верны, ответы от других внешних веб-сервисов приходят с данными, как надо. И в Postman тоже все в порядке - проблема возникает только в bpmonline. Вопрос в следующем - где могут теряться данные? Может ли IIS менять тело ответа? Будем признательны за любую помощь.

У меня такой же вопрос

2 комментария

Что дергает в bpm внешний веб сервис? Привидите код получения и обработки ответа внешнего веб сервиса.

Григорий Чех,

Спасибо за ответ, проблема разрешилась. Дело было в веб-сервисе.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Коллеги, здравствуйте. Возникла проблема - веб-сервис возвращает значения, однако мы не можем их увидеть на преднастроенной странице в bpmonline - в соответствующих полях отображаются 0 (если числовое) и пустота (если строковое). Другие веб-сервисы отображаются корректно, проблема только с одним конкретным. При этом, сам веб-сервис работает корректно, т.е. формирует и отправляет нужный запрос на bpmonline, а дальше мы не можем его отобразить. Используем простой бизнес-процесс, в котором элементы веб-сервис и преднастроенная страница. Будем признательны за помощь

У меня такой же вопрос

1 комментарий
Лучший ответ

Добрый день,

Проблема может быть в типах данных. Если бы вы предоставили скриншоты вашего БП, вам бы быстрей помогли с вашей проблемой.

Добрый день,

Проблема может быть в типах данных. Если бы вы предоставили скриншоты вашего БП, вам бы быстрей помогли с вашей проблемой.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго времени суток, в общем проблема такая. Необходимо отправить на веб сервер данные в формате xml, на сколько я понял из документации элемент "Вызвать веб сервер" отправляет Json запросы  а не XML. Возможно ли отправить запрос в веб сервер в формате XML из элемента "Задание сценарии" или лучше каким нибудь другим ходом пойти? Буду признателен за советы , а желательно с  примером)  

У меня такой же вопрос

1 комментарий
Лучший ответ

Добрый день!
Да, лучше отправьте с помощью задания-сценария с использованием HttpWebRequest.
Пример:

var request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
request.Timeout = timeout * 1000;
using (var dataStream = request.GetRequestStream())
{
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();
}
var resp = (HttpWebResponse)request.GetResponse();

Где postData - строка XML

Добрый день!
Да, лучше отправьте с помощью задания-сценария с использованием HttpWebRequest.
Пример:

var request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
request.Timeout = timeout * 1000;
using (var dataStream = request.GetRequestStream())
{
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();
}
var resp = (HttpWebResponse)request.GetResponse();

Где postData - строка XML

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго времени суток, возникла задача по интеграции с внеш.приложением . В общем у меня есть раздел, у раздела есть кейсы на какой то из стадий нужно отправить данные веб-сервисом.Создал веб сервис добавил его в под-процесс в соответствующем шагу. Насколько эти шаги правильные с точки зрении задачи ? И главный вопрос как стороннее приложение должно ответить чтобы у меня поменялась стадия кейса? Это запуск БП извне или есть более адекватное решение?

У меня такой же вопрос

1 комментарий

Да, элемент «Веб-сервис» в БП для этого и создавался.

В обратном направлнии можно извне либо запустить БП при помощи ProcessEngineService, либо менять значение поля по OData. В обоих случаях сначала нужно залогиниться, используя AuthService и получить CSRF-токен.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго дня, коллеги!

Стоит следующая задача - необходимо считать и отправить данные из объекта на удаленный веб-сервис. Удаленный веб-сервис принимает данные в формате XML. Подскажите пожалуйста, каким образом лучше всего это реализовать - используя бизнес-процессы, DataService или каким-либо другим способом? Заранее благодарю за развернутые ответы. 

У меня такой же вопрос

1 комментарий
Лучший ответ

Добрый день!
Бизнес процесс, в котором скрипт С# с использованием HttpWebRequest.
Пример:

var request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
request.Timeout = timeout * 1000;
using (var dataStream = request.GetRequestStream())
{
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();
}
var resp = (HttpWebResponse)request.GetResponse();

Где postData - строка XML

Добрый день!
Бизнес процесс, в котором скрипт С# с использованием HttpWebRequest.
Пример:

var request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
request.Timeout = timeout * 1000;
using (var dataStream = request.GetRequestStream())
{
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();
}
var resp = (HttpWebResponse)request.GetResponse();

Где postData - строка XML

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день, уважаемое сообщество!

Возникла необходимость передать во внешний сервис список проектов, привязанных к контакту текущего пользователя (под которым была выполнена аутентификация через AuthService.svc). При вызове процесса через  ProcessEngineService.svc я могу получить контакт текущего пользователя и выполнить нужный запрос, но не могу вернуть его результат (или могу?).

А при обращения через OData я могу получить результат запроса, но не представляю, как в него добавить фильтр по текущему контакту.

Подскажите, пожалуйста, как мне быть.

У меня такой же вопрос

2 комментария
Лучший ответ

Посмотрите в академии ПРИМЕРЫ ЗАПРОСОВ НА ВЫБОРКУ С ФИЛЬТРАЦИЕЙ

На вскидку вам надо получить id текущего пользователя в переменую ContactCurrentUserId и вызвать чтото типа

В примере ниже e71dceda-9b0f-4509-aa10-f479aa69a9eb - Id контакта текущего пользователя а фильтрация идет по значению Guid в поле Contact объекта Project

Url сайта>/0/ServiceModel/EntityDataService.svc/ProjectCollection?$filter=Contact/Id eq guid'e71dceda-9b0f-4509-aa10-f479aa69a9eb'

 

Посмотрите в академии ПРИМЕРЫ ЗАПРОСОВ НА ВЫБОРКУ С ФИЛЬТРАЦИЕЙ

На вскидку вам надо получить id текущего пользователя в переменую ContactCurrentUserId и вызвать чтото типа

В примере ниже e71dceda-9b0f-4509-aa10-f479aa69a9eb - Id контакта текущего пользователя а фильтрация идет по значению Guid в поле Contact объекта Project

Url сайта>/0/ServiceModel/EntityDataService.svc/ProjectCollection?$filter=Contact/Id eq guid'e71dceda-9b0f-4509-aa10-f479aa69a9eb'

 

Через OData можно считать SysAdminUnit с фильтрацией по логину пользователя, тем самым получить contactId. А дальше делать уже запрос на выборку и фильтрацию проектов.

Через ProcessEngineService можно получить значение пвраметра (указав название параметра в ResultParameterName), но с интерпретируемыми процессами это работает плохо

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Запускаю из сервиса БП, в котором нет никаких ожиданий.

UserConnection 	userConnection	= HttpContext.Current.Session["UserConnection"] as UserConnection;
var 			manager 		= userConnection.ProcessSchemaManager;
var 			processSchema 	= manager.GetInstanceByName("UsrProcess");
var 			process 		= processSchema.CreateProcess(userConnection);
 
process.SetPropertyValue("ExternalCall", true);
process.Execute(userConnection);

Подскажите, как дождаться завершения БП и прочитать параметры, которые мы имеем в конце выполнения?

У меня такой же вопрос

8 комментариев
Лучший ответ

Добрый день!
Данное действие синхронно, т.е. после завершения операции process.Execute(userConnection); уже можно забирать параметры.
Забирать их следующим образом (пример):

res.Success = process.GetPropertyValue("RpSuccess") != null ? (bool)process.GetPropertyValue("RpSuccess") : false;
res.ErrorDescription = process.GetPropertyValue("RpReturnMsg") != null ? (string)process.GetPropertyValue("RpReturnMsg") : "";

 

Добрый день!
Данное действие синхронно, т.е. после завершения операции process.Execute(userConnection); уже можно забирать параметры.
Забирать их следующим образом (пример):

res.Success = process.GetPropertyValue("RpSuccess") != null ? (bool)process.GetPropertyValue("RpSuccess") : false;
res.ErrorDescription = process.GetPropertyValue("RpReturnMsg") != null ? (string)process.GetPropertyValue("RpReturnMsg") : "";

 

Я бы еще добавил проверку что БП завершен а не свалилися например с ошибкой или еще выполняется, примерно так. 

if (process.Status != ProcessStatus.Running && process.Status != ProcessStatus.Error)

or

if (process.Status == Terrasoft.Core.Process.ProcessStatus.Done)

Как выяснилось, мне нужен интерпретируемый процесс, а там все немного по-другому, а именно

UserConnection 	userConnection	= HttpContext.Current.Session["UserConnection"] as UserConnection;
var manager 		= userConnection.ProcessSchemaManager;
var processSchema 	= manager.GetInstanceByName("UsrPreCreateDealProcess");
var flowEngine 		= new Terrasoft.Core.Process.FlowEngine(userConnection);
Dictionary<string, object> parameter = new Dictionary<string, object>();
parameter.Add("CarId", car_id);
Terrasoft.Core.Process.ProcessDescriptor pd = flowEngine.RunProcess(processSchema, parameter);
if (pd.ProcessStatus == Terrasoft.Core.Process.ProcessStatus.Done)
{
	?????
}

Как вытащить параметры в конце выполнения здесь?

Есть предположение, что копать стоит в сторону FlowEngineStateService, у него есть метод FindProcessComponentSet(Guid processUId), который возвращает инфу о процессе. И там уже забрать параметры

Сидоров Александр В.,

я нашел этот класс, у него есть метод GetParameterValue, но он стабильно возвращает, что параметр не найден по данному пути и возникает (философский) вопрос, что есть Путь? Видимо, это не просто имя. Но товарищи из Террасофта не догадались описать этот момент нигде ни разу.

перепробовал всё с FlowEngineStateService - ничего не работает, написал в ТП

Вообще, не очень хорошо запускать процессы и ждать их завершения синхронно. Ведь процесс может выполняться некоторое время или вообще иметь элементы для общения с пользователем. Лучше будет в самом процессе записывать результаты в какую-то таблицу, а потом периодически её новые записи обрабатывать.

ТП ответила, что решения в 7.11 нет. Я так и знал :)) и заранее сделал обходной путь через БД. Заодно полезное для отладки логирование получилось

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго времени суток, подскажите пожалуйста, как можно задать время выполнения веб-сервиса со сторона JavaScript?

По умолчанию как я понял стоит секунд 30, после отваливается с ошибкой "Превышен лимит времени выполнения запроса к серверу приложений статус ответа..."

Вызываю обычный сервис так:

ServiceHelper.callService("ServiceName", "ServiceMethodPost", function(response) {
	window.console.log(response);
}, serviceData, this);

 

У меня такой же вопрос

5 комментариев
Лучший ответ

Сериков Асхат Кайратович,
Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {
 
	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}
 
	return {
		callService: internalCallService
	};
});

 

Добрый день!
Timeout указывается в конфиге вызова сервиса (параметр timeout).
В вашем случае будет так:

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

 

Сидоров Александр В.,
Спасибо

var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService("ServiceName", "MethodName", function(response) {
	window.console.log(response);
}, serviceData, this);

В моем случае в serviceData есть другие параметры веб сервиса, их нужно будет в отдельный объект выложить? Не совсем понимаю как БПМ определит что является обычным параметром, а что конфигурационным

Сериков Асхат Кайратович,
Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {
 
	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}
 
	return {
		callService: internalCallService
	};
});

 

Сидоров Александр В.,

Понял, пойду попробую спасибо,

Сидоров Александр В.,

В целом все так как вы и сказали, только раз присутствует конфиг, то все остальные параметры(данные, scope, callback) нужно так же перенести в него, иначе они перезатрутся при вызове. Спасибо!

Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

Вопрос:

Возникла необходимость разобрать массив с большим кол-вом данным.  На академии такой пример не рассмотрен.
В курсе о возможности парсинга массива при настройке параметров JSONPath, но это работает при условии возвращения одной записи в массиве. А как быть с большим кол-вом данных?

При настройке обработки ответа веб-сервиса, есть поле "Является массивом", при его активации, ответ конвертируется в интерфейс IObjectList, и записать его в параметрах бизнес процесса представляется возможным только с типом данных "Коллекция значений", что усложняет парсинг массива.

Вопросы:
Что за интерфейсы IObjectList/ICompositeObject/ICompositeObjectList<TObject>, и как обрабатывать такой конвертированный массив?
Можно-ли обработать массив из ответа веб-сервиса и как это сделать?

Веб-сервис http://hetzner1.k-matika.ru:64123/0/rest/KmWebService/GenderSearchContact?GenderName={значение}, выборка по полу {Male/Female}

Выборка полей по каждому контакту: Id, Name, Phone

Ответ:

Пример реализации:
Сервис (схема):

Рекомендации: используйте контракты для передачи объектов, для формирования json, используйте возможности newtonsoft.json
Бизнес-процесс:

Сервис


Настройки элемента "Вызвать веб сервис"


Настройки элемента "Задание-сценарий":

Поделиться

1 комментарий

ICompositeObjectList представляет собой массив элементов ICompositeObject. Перебирается обычным циклом (foreach).
ICompositeObject - dictionary (ключ-значение).
Получить значение можно одним из 2х методов:
 

/// <summary>Returns inner value by key.</summary>
    /// <param name="key">The key.</param>
    /// <param name="valueType">Type of the value.</param>
    /// <param name="value">Result value.</param>
    bool TryGetValue(string key, Type valueType, out object value);
 
    /// <summary>Returns inner value by key.</summary>
    /// <typeparam name="TValueType">The type of the value.</typeparam>
    /// <param name="key">The key.</param>
    /// <param name="value">Result value.</param>
    bool TryGetValue<TValueType>(string key, out TValueType value);

 

Войдите или зарегистрируйтесь, чтобы комментировать