Web сервисы 1С:Предприятия 8.2 или как с ними бороться.

Введение

На данный момент механизм вебсервисов 1С:Предприятие 8.2 имеет ряд ограничений и ошибок, которые не позволяют реализовать интеграцию 1С с внешними системами без использования дополнительных средств, призванных исправить эти ограничения.
Целью статьи является описание технических проблем в механизме вебсервисов 1С:Предприятия 8.2 и рекомендаций по их решению.

Предыстория

Некоторое время назад мне довелось поучаствовать в процессе интеграции
1С:Предприятие 8.2 с корпоративными системами компании. Сразу скажу, что 1С
в компании хоть и является активно используемой, но не является главной. В
компании есть SAP (и не один - FI/MM/SRM и пр.). Кроме того, в качестве
корпоративной шины данных используется SAP PI (он же в прошлом XI). С точки
зрения интеграции PI является мастер-системой, т.е. она формулирует общие
правила для интеграционных решений. Все интеграционные решения в компании должны
строиться через PI, при этом для внешних систем по отношению к SAP должны
использоваться Web-сервисы (хотя других особо возможностей и нет, как я думаю).

Т.е. если нужно организовать интеграцию двух систем, в которой одна система
выступает как сервис и другая как клиент, то в PI будет поднят сервис, идентичный
сервису первой системы кроме точки доступа, и через который вторая система будет
обращаться к первой через систему PI.

Общий порядок выработки решений построен таким образом, что сначала интегрируемые
системы (допустим FI и 1С) договариваются о составе данных и бизнес логики. Потом
они выходят с выработанным пониманием (проектным решением) к PI. PI (не сама конечно,
а высокооплачиваемые специалисты) дорабатывают проектное решение на предмет формата
сервисов и структуры данных. В частности выдают спецификации WSDL и XSD Web-сервисов.

В силу того, что компания большая и развита бюрократия, то по регламенту спецификация
выдаваемая PI является окончательной. Это означает, что если с т.з. спецификаций
SOAP, XSD Schema и WSDL она не противоречит, то системы обязаны ее реализовать.
И тут начинается самое интересное. С точки зрения спецификации контракта WSDL операция
может реализовываться по разному, а 1С может реализовывать операцию только определенным
способом и никак иначе. Поясню это на примере.

Проблема раз: "Описание операции в контракте"

Допустим, в 1С должен быть создан сервис, предоставляющий информацию о книгах в магазине. Сервис получает ISBN книги, а на выходе получает описание книги. WSDL который предоставляет PI выглядит так:

Листинг 1

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

	
	
		
	
	
		
	
	
		
	
	
		
			
			
		
	
	
		
		
			
			
				
			
			
				
			
		
	
	
		
			
		
	

Типы в схеме указаны через тэг:

Листинг 2


и пока не интересны.

Так как платформа 1С не позволяет создать автоматически вебсервис из WSDL, разработчику приходится вручную создавать соответствующий сервис в конфигураторе 1С. При создании вебсервиса в конфигураторе, разработчик должен определить операцию, а потом его реализовать. Допустим он определит ей имя - “getBookByISBN”, а имя методу, который будет вызываться в 1С -“getBookByISBNRequest”.
После создания вебсервиса и его публикации в 1С, платформа сама создает артефакты вебсервиса и
WSDL который мы получаем из 1С будет выглядеть следующим образом:

Листинг 3

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

	
		
			
			
			
			
				
					
					
					
				
			
			
				
					
				
			
			
				
			
			
				
					
						
					
				
			
			
				
					
						
					
				
			
		
	
	
		
	
	
		
	
	
		
			
			
		
	
	
		
		
			
			
				
			
			
				
			
		
	
	
		
			
		
	

Обратите внимание, что в схему данных платформа самостоятельно добавила элементы getBookByISBN и getBookByISBNResponse. Хотя мы ничего такого не хотели, но в то же время если мы выгрузим соответствующий XDTO в файл, то этих элементов не обнаружим. Это означает, что 1С неявно (или явно, кому как угодно) описала новую по сути структуру операции, «вложив» исходный message в операцию, созданную в платформе.

Для наглядности сравните SOAP сообщение, которое теперь ожидает получить 1С на входе:

Листинг 4


	
		
			String
		
	

с сообщением, которое будет выдавать PI

Листинг 5


	
		String
	

Очевидно, что 1С не всасет такое сообщение. Что делать? При обращении в 1С был получен ответ, что нужно привести контракт описания сервиса к формату 1С. Но позвольте, как тогда с тем, что по общему мнению сервисы считаются универсальным средством интеграции. Где тогда тут универсальность? Кроме того, с чего это PI должен изменять WSDL? Вообщем очевидно, что 1С не поддерживает в полной мере спецификацию вебсервисов. По причине того, что определением структуры вебсервиса разработчик 1С напрямую не управляет и платформа 1С сама создает артефакты, то в общем случае невозможно создать вебсервис в 1C точности заданной структуры внешней системой. Вследствие чего невозможно реализовать интеграцию, используя только штатные средства 1С.

Проблема два: "Изменение namespaces"

При загрузке документа XML-Schema в объекты XDTO платформа игнорирует значение атрибутов elementFormDefault и attributeFormDefault документа, неявно считая их значением равным qualified и unqualified соответственно. Это приводит к тому, что после загрузки XML-Schema из внешней системы в 1С в котором elementFormDefault указан как unqualified, XML документ выгружается из 1С с явным присвоением префиксов элементов.
Покажем это на примере. Пусть имеется исходная XML-Schema с описанием типов:

Листинг 6

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


	
	
	
	
		
			
			
			
		
	
	
		
			
		
	
	
		
	

Так как элемент elementFormDefault не упомянут в схеме, то считается, что его значение неявно установлено в «unqualified». Во внешней системе (у нас стало быть PI) XML документ, соответствующий схеме будет таким:

Листинг 7

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

	
		Alice's Adventures in Wonderland
		Lewis Carroll
		978-0-86203-324-8
	
	
		Waltzing with Bears: Managing Risk on Software Projects
		Tom DeMarco
		5-902681-03-0
	

В то же время, после загрузки схемы в 1С в объект XDTO, то схема в 1С «преобразуется» к виду:

Листинг 8


	
	
	
	
		
			
			
			
		
	
	
		
	
	
		
			
		
	

Обратим внимание на появление атрибутов elementFormDefault и attributeFormDefault, хотя в исходной схеме (Документ1) их не было! С точки зрения корректности XML схемы загруженной в 1С по отношению схеме из внешней системы все правильно. Схема в 1С описывает структуру типов и пространство соответствующих исходной схеме (которая бала загружена в 1С). Однако, добавленный атрибут elementFormDefault указывает, что элементы выгруженные из 1С должны сопровождаться префиксом пространства имен. Тот же объект «store» из 1С будет выгружен так:

Листинг 9

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

	
		Alice's Adventures in Wonderland
		Lewis Carroll
		978-0-86203-324-8
	
	
		Waltzing with Bears: Managing Risk on Software Projects
		Tom DeMarco
		5-902681-03-0
	

Как видим, в документе из 1С в некорневых элементах так же наличествуют префиксы пространства имен. Это определяется тем, что значение атрибута attributeFormDefault установлено в значение qualified. Рассмотрим теперь ситуацию, когда внешняя система (PI) участвует в обмене данными через механизм вебсервисов с 1С. При этом WSDL и XML-Schema предоставляется опять же таки PI. В этой ситуации, PI и 1С не смогут обмениваться сообщениями, так документ Листинг 9 при поступлении во внешнюю систему из 1С не пройдет валидацию по отношению к схеме (во внешней системе) Листинг 6, а документ Листинг 7 при поступлении в 1С не пройдет валидацию по отношению к схеме Листинг 8.

Загрузка XML-Schema в 1С происходит с ее изменением. Это изменение по сути означает, что на самом деле схема в 1С и во внешней системе (PI) различны. В результате, сообщение от одной системы к другой не проходят процедуру валидации.
Если привести схему во внешней системе к виду схемы в 1С нет возможности, то необходимо каким то образом трансформировать сообщения из одного формата в другой и наоборот.

Проблема три: "SOAP-ENV:Header"

Платформа 1С:Предприятие 8.2 не поддерживает заголовок SOAP. При получении заголовка 1С игнорирует его. При отправке сообщения нет возможности сформировать заголовок.
Это означает что 1С не может выступать в качестве промежуточного SOAP сервера.

Решение

Если вы дочитали до этого места, вас возможно заинтересует решение, которое было написано для решения вышеописанных проблем. Решение представляет собой прокси, которое преобразует "на лету" входящие и исходящие данные. Web Proxy Adapter предназначен для преобразования xml сообщений, передаваемых по http протоколу между клиентом и сервером. Адаптер можно использовать для преобразования сообщений между web-сервисами, при этом к преобразованию доступно все SOAP сообщение. Преобразования сообщений осуществляется с помощью применения XSLT преобразований. Сам адаптер данные не изменяет. Все изменения с данными осуществляются только через применение XSLT шаблонов.
Технические характеристики:

  • Адаптер является web-приложением с использованием технологии Java servlets.
  • Адаптер может работать на любым web сервере, поддерживающим работу Java servlets.
  • Одно приложение может обслуживать несколько соединений между клиентами и серверами.
  • Преобразования сообщений осуществляется через XSLT (версии 1.0) , применяемое отдельно к входящему потоку и отдельно к ответу от сервера.
  • Возможность настройки логирования проходящих данных через адаптер в нужном виде и на нужное устройство.
    Технические требования:
  • Web сервер, поддерживающий java servlet 2.0 или более поздней версии (например Apache Tomcat).
  • JRE 1.5 или выше.
  • Открытые порты на входящее и исходящее соединения (в соответствии с настройками в proxy-config.xml).

Работу адаптера можно представить в виде схемы:
Web Proxy Adapter

Заключение

Решение WPA позволяет не только исправить недоработки платформы 1С, но так же предоставляет возможность логирования сообщений еще перед тем, как они попадут в 1С или наоборот выйдут из 1С. Это весьма полезно на этапе отладки вебсервисов на стороне 1С, так как помимо упомянутых ошибок платформы есть и другие, менее значимые и что бы разобраться с ними необходимо видеть что именно приходит и выходит из 1С. Некоторые ошибки вообще можно только так и определить, так как сама 1С либо никак себя не проявляет (молчит и все) либо "падает"

Инструкция: кликните по имени файла для начала скачивания

Описание и имя файла Размер
Web Proxy Adapter
WebProxy-1.1.67.zip
3 442 K

При перепечатке данной статьи или ее цитировании ссылка на первоисточник обязательна: Копирайт © 2011 gildebrand – Web сервисы 1С:Предприятия 8.2 или как с ними бороться.

Комментарии

Никак не получается подкинуть

Никак не получается подкинуть файлы шаблонов. Использую tomcat на debian. Файлы шаблонов положил в WEB-INF, в proxy-config.xml прописал полные пути до этих файлов: <transform-in>/var/lib/tomcat6/webapps/WebProxy/WEB-INF/in.xsl</transform-in> <transform-out>/var/lib/tomcat6/webapps/WebProxy/WEB-INF/out.xsl</transform-out> Пробовал также прописывать просто in.xsl и out.xsl. Прокси отрабатывает, но преобразования не применяет. В логе никаких ошибок нет, только http-8080-1 INFO Rules - done Не подскажете, в чем может быть проблема?

Проверь, чтобы в дескрипторе

Проверь, чтобы в дескрипторе развертывания (web.xml) у тебя были правильно прописан пути к proxy-config.xml и логгеру log4j:

...
    
        Proxy
        ru.greenatom.Proxy

        
            proxy-config
            /WEB-INF/proxy-config.xml
        
        
        
            log-config
            /WEB-INF/log4j.xml
        
        
    
...

Не могли бы Вы привести

Не могли бы Вы привести пример реально работающего файла конфигурации? Конкретно меня интересуют параметры transform-in и transform-out. Какой сервер Вы используете и под какой ОС?

Сервер Apache, ОС Win

Сервер Apache, ОС Win

С самими proxy-config.xml и

С самими proxy-config.xml и log4j.xml проблем нет, т.к. прокси дергает web-сервис, прописанный в url и лог пишется в файл, настроенный в log4j.xml. Проблема только в том, что прокси не применяет XSLT-преобразования. И я понять не могу, что ему не нравится

Попробуй такую настройку

Попробуй такую настройку log4j.xml:

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

	
		
			 
		
	
	
	
        	
        	
        	        
    			
        	           
	

	
		
		
	

	
		
 		

	
	


В настройках proxy-config.xml должно быть что то вроде такого:

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

	
		
			/WebProxy/proxy/test/ws/documentum.1cws
			000091. DO.  IN.RXP
			
			TRUE
			http://10.124.8.125/test/ws/documentum.1cws
			/WEB-INF/documentum-in.xsl
			/WEB-INF/documentum-out.xsl
			
			
		
	

Перезапусти WPA, обратись по url http://ADRES_GDE_ZAPUSCHEN_WPA/WebProxy/proxy/test/ws/documentum.1cws и посмтри что записалось в proxy.log?

Имена шаблонов надо указывать

Имена шаблонов надо указывать в виде /WEB-INF/template-name.xsl. Спасибо, помогло!

Если будут мысли, что можно

Если будут мысли, что можно улучшить/исправить - пиши, постараюсь быстро включить.

В каталоге lib Apache есть

В каталоге lib Apache есть xalan.jar и xercesImpl.jar?

С библиотеками тоже вроде все

С библиотеками тоже вроде все в порядке. Сразу после установки сервлет сыпал исключениями (по поводу log4j в частности). В каталоге WEB-INF создал подкаталог lib и туда подкинул все jar-файлы, что идут с сервлетом. После этого сервлет заработал

Отличная статья! Чувствуется

Отличная статья! Чувствуется Вас WS в 1С сильно пробрали. И вопросик: а на PI трансформацию сделать по какой причине нельзя было? Почему такой воркэраунд получился?

В PI не делали трансформацию

В PI не делали трансформацию отчасти из идеологических соображений (best practice :)) отчасти из-за того, что по общей схеме (wsdl, xsd) интеграция общая, как с SAP системами так и с не SAP. Ограничение платформы 1С в построении WS - 1С-ом трактуется как "специфика" 1С, а SAP-ом как ограничение, которое не должно влиять на смежные системы работающие через единый интерфейс.