Logo    
Продукты, технологии Проекты, внедрения Новости мира IT Форумы Курилка Новые публикации Учебный центр
CitForum    CITForum на CD Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware HOWTO

22.10.2004

[an error occurred while processing this directive]
Google
WWW CITForum.ru

2003 г

WSDL: взгляд изнутри, часть I

Автор: Джоан Питерз (Johan Peeters)
Перевод: Intersoft Lab

Недавно автору статьи довелось использовать язык WSDL (Web Services Description Language, Язык описания Web-сервисов) для нескольких существующих Web-сервисов - на одном клиенте работал сервер и клиентская реализация. У этого клиента и специалистов по обслуживание сервера уже сложились тесные рабочие отношения, но наступил момент, когда возникла необходимость в еще одной клиентской реализации, которую должна была выполнить группа разработчиков, находящихся в противоположенной точке земного шара. В связи с этим потребовалась четкая спецификация, описывающая такие сервисы, а именно для этого и предназначен WSDL. Поэтому автор вознамерился основательно изучить то, что ранее не было достаточно освещено. В результате, он приобрел ценный опыт - ему удалось вспомнить старую и добрую практику проектирования программного обеспечения и обнаружить ряд проблем, характерных для Web-сервисов, WSDL и XML Schema.

В самом начале, на этапе проектирования, было допущено несколько ошибок, которые изначально трудно заметить. Вероятно, эти недочеты не были бы допущены, если бы проектировщики дали формальное определение для своих сервисов на WSDL. Так что, вот основная мысль этих двух статей: пишите WSDL заранее, не генерируйте его потом, как это часто советуют поставщики.

При всем внимании, которым были одарены Web-сервисы, часто сложно отделить желаемое от действительного. В предлагаемом цикле статей акцент будет сделан на реальном, а не на потенциальном. В них читатель не найдет краткого обзора WSDL, кроме того предполагается, что он знаком с W3C XML Schema. В первой статье рассказывается, чем могут быть полезны при проектировании Web-сервисов практика проектирования программного обеспечения и опыт в области распределенной обработки данных. В ней рассматриваются некоторые решения, которые должен принимать проектировщик Web-сервисов, приводятся необходимые советы и рекомендации. В остальных статьях будет описан процесс проектирования: во второй статье будут перечислены некоторые "темные стороны" спецификации WSDL 1.1. В нее не войдут определения типов данных - темы третьей статьи, в которой будет представлена W3C XML Schema с позиции того, кто использует ее для определения данных, передаваемых через интерфейсы Web-сервисов.

Проектирование Web-сервисов

Употребляемый автором термин Web-сервисов относится исключительно к тому виду технологии, которая состредоточена на взаимодействии (interoperability). Это означает, что эта технология стандартизирована: гетерогенные системы работают только при наличии отрытых стандартов. В этом случае уместен вопрос: будут ли Web-сервисы решением вашей проблемы? Сегодня одного слова Web-сервисы уже недостаточно, чтобы говорить о солидности компании, их использующей, поэтому будет лучше, если имеются иные веские основания для их использования. Если вы контролируете оба конца канала, не исключено, что существуют более подходящие технологии. Сейчас - только заря эры открытых стандартов распределенной обработки данных. Поэтому цена поддержки Web-сервисов на этом еще несформировавшемся рынке остается высокой - это и снижение производительности, и увеличение затрат на разработку, и ухудшение защищенности.

Тезис о том, что Web-сервисы являются "дружественными по отношению к брандмауэру" ("firewall friendly"), обманчив. Действительно, обычные брандмауэры оберегают корпоративные ценности от "злоумышленников", которые используют слабые места в прикладном программном обеспечении, появившиеся в результате открытия портов, на которых исполняются защищённые сервисы. С другой стороны, Web-сервисы через этих порты "выставляют" прикладное программное обеспечение. Другими словами, они ослабляют безопасность, предоставляя посторонним лицам доступ к приложениям - именно то, чему сетевой брандмауэр должен был бы воспрепятствовать. Поэтому необходимо новое поколение брандмауэров. На рынке уже появилось несколько новых игроков, предлагающих такие продукты. Поставщики обычных брандмауэров также начинают обращать внимание на эту проблему. Но это только начало, и такая технология должна еще оправдать себя.

Даже если предполагается применять Web-сервисы, необходимо помнить, что необязательно использовать SOAP. Например, автор статьи видел формы, передаваемые как аргумент запроса на удаленный вызов процедуры SOAP (SOAP-RPC). Ему также попадались формы, которые возвращались как часть ответа удаленного вызова процедуры SOAP. Он так и не смог найти дополнительную пользу от применения SOAP. Разве не был бы проще обыкновенный XML или HTML через HTTP?

Недопустимость генерации WSDL

Ответим на вопрос: предназначен ли WSDL 1.1 для восприятия человеком. Типичный совет - генерировать WSDL, а не писать вручную. Автор по этому вопросу придерживается следующего мнения. Возможно, это и верно, если таким образом разрабатывается простой, демонстрационный сервис, но данный подход обречен на провал, когда он применяется к крупным системам. Даже программист, работающий самостоятельно, быстро утратит общее представление о проблеме; ситуация усложняется если разработку совместно ведут различные, территориально разнесенные группы специалистов. Большие распределенные системы требуют проектирования; ожидание того, что после объединения они будут совместно работать, приведет к катастрофе.

Если распределенные компоненты могут разрабатываться на различных языках программирования, то для того, чтобы указать, как должны быть задействованы сервисы, необходим Язык описания интерфейсов (Interface Definition Language, IDL), нейтральный по отношению к языку программирования. У CORBA (Общая архитектура посредника запросов к объектам, Common Object Request Broker Architecture), как и у DCOM (Распределенная модель компонентных объектов, Distributed Component Object Model), такой язык есть. IDL - это контракт между инициатором на обслуживание и поставщиком, но он только собирает синтаксис. Семантика остается неосвещенной: IDL оставляет открытым вопрос о том, что делает сервис.

WSDL - это IDL Web-сервисов. Он описывает, как вызывать Web-сервисы. Он также определяет ответы, которые могут быть получены как при успешном вызове, так и нет. Спецификация WSDL жестко регламентирует формат сообщений, используемые протоколы и адрес, по которому находятся сервисы. К сожалению, даже четкое и строгое описании на WSDL не гарантирует высокое качество проектирования. Подобно всем языкам IDL, WSDL силен в синтаксисе и слаб в семантике. Однако, не стоит им пренебрегать - в конечном счете важна именно семантика, синтаксис же используется просто, чтобы ее раскрывать.

Проектирование интерфейсов

Прежде чем приступить к написанию WSDL, необходимо оговорить с заказчиками то, что Web-сервис должен делать. Следует записать случаи использования, четко определив, как этот сервис взаимодействует со своей средой. Предположим, что программа-агент (actor) с какой-либо целью вызывает Web-сервис. В этом случае, нужно создать не только сценарий "солнечного дня", который реализует поставленную задачу, но сценарий "дождливого дня", когда результат отрицательный. Какие гарантии может предложить система, что цель успешно достигнута? А когда нет? Где находится граница ответственности клиентской части и сервера?

Трудно переоценить важность четкого определения требований. На этом этапа стоит задуматься о цели проекта. В чем конкретно она заключается? Какие данные необходимо получать от клиента, и что должен поставлять сервер? Совершение ошибки на этом шаге чревато большими затратами.

Например, рассмотрим Web-сервис, который в качестве параметров принимает список установленных программ и величину свободного места на диске. Затем этот сервис должен вернуть список приложений, подлежащих обновлению. В случае если места достаточно, проблем не возникает. Однако, как быть, если его недостаточно? Как выбрать продукты, для которых необходимо установить новые версии? Предполагается ли, что клиент сам удаляет старые редакции программ, чтобы освободить место для новых? Это непростые вопросы, для решения которых потребуется разрабатывать сложные алгоритмы, при реализация которых не исключены ошибки. Разумеется, ни одну систему не следует определять подобным образом. Сервер должен предоставлять список приложений, зависимости между ними и требования, которые они предъявляют к ресурсам. Решение же о том, какой пакет установить, является задачей клиента. Поэтому поручив серверу это задание, клиент ничего не выиграет, он только повысит затраты на разработку серверной части.

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

Следующий шаг - проанализировать, как можно реализовать случаи использования. Будет ли единственный интерфейс (portType в WSDL версии 1.1), обеспечивающий всю функциональность? Или несколько интерфейсов? Каждый интерфейс может быть предложен в нескольких конечных точках, но, как правило, он должен быть неделимым. То есть конечная точка должна предоставлять либо всю функциональность, либо ничего. Аналогично, интерфейс должен быть семантически последовательным. Сказанное носит рекомендательный характер и опирается на здравый смысл, хотя ничто в спецификации WSDL не препятствует иной интерпретации.

Требуются ли какие-нибудь поддерживающие интерфейсы? Как и когда они должны вызываться? Какова природа этой зависимости? Пока нет стандартов, а только рекомендации о том, как обращаться с "хореографией сервисов" (service choreographies), как разрешать сервисам выполнять гиперссылки к другим сервисам. Другими словами, это неисследованная проблемная область.

Возвращает ли разрабатываемый сервис результат клиенту? Должен ли клиент располагать информацией о том, что сервис успешно отработал? Должен ли клиент вызывать сервис синхронно? Или асинхронно? Или же сервис будет поддерживать оба типа вызова?

Непрозрачность сети

Сеть не является прозрачной - вызов локального сервиса и его удаленный вызов существенно отличаются друг от друга. В качестве "памятки разработчику" можно порекомендовать тезисы Питера Дойча (Peter Deutsh) "Восемь заблуждений о распределенной обработке данных" (eight fallacies of distributed computing).

Неверная семантика различна для сетевого окружения и локальной реализации: при неудачном вызове не всегда известно, исполнился сервис или нет.

WSDL 1.1 описывает следующие виды вызовов: односторонний (one-way), запрос-ответ (request-response), ответ на требование (solicit-response) и уведомление (notification). Однако, связывания WSDL поддерживают только односторонний вызов и вызов вида запрос-ответ. Также следует понимать, что реально, а что - нет. Другими словами, сегодня невозможно реализовать ситуацию, когда клиент ожидает с сервера асинхронное получение практического, "промышленного качества" и согласованного со стандартами результата. Это следует расценивать как досадное обстоятельство, поскольку это именно тот механизм, который является наиболее гибким в ситуации частичного сбоя.

WSDL позволяет перемешивать и согласовывать виды вызова и транспорт (transport). На этом этапе важно прибегнуть к здравому смыслу. Первое требование - а это не всегда очевидно - необходимо четко представить, как стек протоколов предлагаемого Web-сервиса будет себя вести. В качестве примера рассмотрим, что случится если асинхронно вызвать Web-сервис поверх механизма синхронного транспорта. Предположим, что SOAP-сообщение пересылается в одну сторону по HTTP: бизнес логика на клиенте формирует SOAP сообщение, чтобы вызвать удаленный сервис. В результате запрос HTTP посылается на сервер. Когда сервер получает запрос, он должен немедленно возвратить ответ HTTP, не обслуживая этот запрос. Бизнес логика на сервере должна отрабатывать после того, как этот ответ был возвращен. Этот ответ не должен содержать SOAP-сообщение. Ответ HTTP с кодом состояния 200 или 202 не означает, что сервис успешно отработал. Код сбоя, с другой стороны, должен гарантировать, что вызов сервиса не исполнился. Слой SOAP на клиенте не формирует новых сообщений до тех пор, пока он не получит ответ, или пока не истечет время ожидания.

Таким образом, односторонний вызов не "устраняет" задержки или неисправности в сети. Самое большее - он помогает избежать задержки с бизнес логикой на сервере. Автор употребил "самое большее", подразумевая, что эту функциональность стоит протестировать на инструментальной цепочке сервера, прежде чем полагаться на нее -корректная реализация является нетривиальной задачей для любого поставщика.

Используя HTTP в в качестве транспортного протокола, клиент может быть уверен, что его запрос был доставлен. Стоит заметить, однако, что если клиент не получил ответ, это не значит, что сервер не получил и не обработал корректно этот запрос. Например, сеть может "упасть" во время отправки ответа. Другими словами, реализовать вызов просто, правильно завершенный вызов - нет.

Отличие Web-сервисов от распределенных объектов

Объекты характеризуются состоянием. Следует избегать состояния, поскольку оно связывает ресурсы и ослабляет масштабируемость. Слабосвязанная архитектура разрешает отдельным компонентам изменяться, не разрушая систему. Весьма вероятно, что в будущем потребуется расширять Web-сервис. Как же при этом сохранить обратную совместимость?

Несмотря на то, что достоинство удаленного вызова процедуры (RPC) в легкости реализации, он не очень хорошо уживается со слабой связанностью: необходимо передавать фиксированный список параметров при каждом вызове Web-сервиса. Эту проблему можно в некоторой степени сделать менее острой, разрешив некоторым параметрам "не иметь значения". Оставим без рассмотрения возникающие в этом случае проблемы, связанные с обеспечением возможности взаимодействия, - более фундаментальное ограничение заключается в том, что этот прием позволяет исключать параметры, а не добавлять их. Вызовы в стиле документа проявляют себя лучше, когда части документа могут быть определены как необязательные. Они также могут быть спроектированы для расширяемости.

Определение ограниченных интерфейсов

Следует внимательно изучить то, что предлагается: и на уровне данных, и на уровне кодирования данных. Необходимо помнить, что придется продолжить поддерживать поставляемый интерфейс. Чем ограниченнее интерфейс, тем легче его реализация. WSDL же спроектирован для гибкости.. Из-за этой гибкости легко ошибиться в спецификации Web-сервисов и оставить многие опции реализации неохваченными . Следует избегать этого - клиенты и серверы должны уметь обрабатывать все сообщения, которые допустимы по контракту.

Типичная ошибка, совершаемая при реализации серверных систем, - установление соединения с базой данных при каждом запросе к этой базе. Автор совершил такую ошибку - выяснилось, что установление соединения с базой данных занимает больше времени, чем все остальное, вместе взятое. Чтобы минимизировать это падение производительности, можно прибегнуть к одному из двух приемов: воспользоваться пулом соединений (connection pool) или хранимой процедурой.

При использовании Web-сервисов стоимость установки соединения также высока. Опять-таки дополнительные затраты на вызов могут быть уменьшены повторным использованием существующего соединения. С другой стороны, необходимо учитывать, что поддержание открытого соединения требует ресурсов. Однако, важно помнить, что расходы, связанные с вызовами Web-сервиса, гораздо более высокие по сравнению с вызовом локальной функции и, следовательно, их следует реже использовать.

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

Тем не менее, хранимые процедуры решают реальную проблему, и их недостатки должны быть соотнесены с достоинствами в каждом отдельном случае. Аналогично, в области Web-сервисов, клиенту предоставляется контроль над логикой за счет множества мелко структурных вызовов. Крупно структурные сервисы более напоминают хранимые процедуры. Они не только улучшат производительность, но и упросят процесс реализации, внедрения и управления всей системой.

Итак, практическая рекомендация - проектировать Web-сервисы под ограниченные, но крупно структурные интерфейсы. Ограниченность позволяет показывать как можно меньше, крупность структуры - выполнять как можно больше для одного вызова.

Разнесение бизнес логики и политики

Не следует реализовывать аутентификацию и авторизацию в бизнес логике. Безопасность транспортного уровня может быть как удовлетворительной, так и нет. В разделе Ресурсы приведены ссылки на статьи, в которых рассматривается этот вопрос. Даже если безопасность транспортного уровня и не урезается, все равно пока нет стандартов - они только разрабатываются, и из них стоит отметить создаваемые Техническим комитетом OASIS "Защищенность Web-сервисов" (OASIS Web Services Security Technical Committee). Предлагаемые подходы действительно способствуют разделению бизнес логики и политики (policy): заголовки SOAP вставляются в сервис, чтобы обеспечить характеристики безовасности, а информативная часть сообщения сохраняется для бизнес логики.

Но как же без ложки дегтя - предлагаемый стандарт применим только к Web-сервисам, использующим SOAP. Еще одна неприятность - отсутствие стандартизированного способа указать Качество защиты (Quality of Protection, QoP) сервиса в документе WSDL. Microsoft, BEA, SAP и IBM опубликовали спецификацию для "Приложений политики Web-сервисов" (Web Services Policy Attachments), в которой рассматривается этот вопрос. Насколько известно автору, этот документ еще не был передан ни в один орган стандартизации.

Разделение проектирования и реализации

В идеале при проектировании Web-сервисов следует оставить вопросы реализации в стороне. Суть проектирования -посмотреть на систему на высоком уровне абстракции, не обращая внимания на проблемы реализации. Однако, можно выбрать такой, казалось бы подходящий по всем параметрам дизайн проекта, который окажется бесполезным, если инструментальные цепочки, которые предполагается использовать, не поддерживают конструкции в разработанном WSDL. Автор настойчиво рекомендует создание макета по техническим спецификациям для проверки реальности осуществления проекта. Пока этот момент еще не проработан.

Благодарности

Автор выражает глубокую благодарность Марку Портайеру (Mark Portier) и Кэролайн Гринмен (Caroline Greenman) за их конструктивные замечания.

Ресурсы

"Мыльная опера" на тему защищенность Web-сервисов будет продолжаться еще долго. Ниже приведено "содержание первых серий":

  • В цикле статей "Защищенность Web-сервисов" (Web Services Security) Билала Сиддикуи (Bilal Siddiqui) описывается "дырка", которую создали основанные на SOAP Web-сервисы;
  • В своей статье "Web-сервисам необходим брандмауэр" (XML Web services need a firewall) Керри Чемпион (Kerry Champion) выступает за использование брандмауэров XML;
  • В статье "Брандмауэры XML" (XML Firewalls) Престона Гралла (Preston Gralla) содержится упоминание о некоторых текущих коммерческих реализациях;
  • Спецификация "Ценные качества Web-сервисов" (Web Services Goodness (WS-Goodness)) разрешает все известные проблемы защищенности.

В статье "IDL, которого нет" (The IDL That Isn't) Мартина Гуджина (Martin Gudgin) и Тимоти Иуолда (Timothy Ewald) приводится более глубокий анализ WSDL с позиций IDL.

В белой бумаге "Кто пишет контракты Ваших Web-сервисов" (Who Writes Your Web Service Contracts?) корпорации Karniak рассказывается о том, как точное описание упрощает процесс разработки Web-сервиса.

Ближайшие курсы Центра Информационных Технологий:

25-28 октября 2004, Москва
Введение в объектно-ориентированный анализ и проектирование и унифицированный процесс разработки программного обеспечения c использованием языка UML и CASE-средства IBM Rational Rose

1-4 ноября 2004, Москва
Современные технологии анализа и проектирования информационных систем

1-5 ноября 2004, Москва
Основы передачи данных

9-10 ноября 2004, Москва
Основы моделирования бизнес-процессов и спецификации требований к ПО

Подписка на новости библиотеки:

Новые поступления в on-line библиотеку:

19 октября

  • Функциональная безопасность программных средств
  • Технологические процессы и стандарты обеспечения функциональной безопасности в жизненном цикле программных средств
  • Так как же восстановить данные таблицы?
  • Использование CAST и табличных функций в PL/SQL

    14 октября

  • Разрезая биллионы
  • Платформа, которой не существует
  • Intel 9xx: время тестов
  • Сбалансированная система показателей: краткий обзор рынка программного обеспечения
  • Кросс-браузерность: теория и практика

    12 октября

  • В борьбе за каждый миллиметр
  • Хранилища данных и семантические разрывы
  • BI и ССП: связь между ними
  • Десять заповедей резервного копирования

    7 октября

  • XML-СУБД Sedna: технические особенности и варианты использования
  • Хранилище данных: вопросы и ответы
  • Порядок разработки ETL-процессов

    5 октября

  • Использование сокетов в Delphi
    Часть первая: стандартные сокеты
    Часть вторая: сокеты Windows
  • Задачи и аналитическая платформа для ВРМ
  • Методики, технологии и инструменты ВРМ
  • Выбор системы управления эффективностью бизнеса: решающие факторы

    30 сентября

  • MySQL: Руководство разработчика
  • MySQL: Руководство по ODBC и MyODBC

    28 сентября

  • СУБД ЛИНТЕР. Технический обзор
  • Новое в СУБД ЛИНТЕР 6.1
  • Использование ЛИНТЕР в качестве встроенной СУБД

    21 сентября

  • Материалы книги П.Б.Храмцова "Система доменных имен"
  • Храните свои терабайты в ящике
  • Тестирование контроллеров iSCSI
  • Девять ошибок, которые могут помешать работе SAN

    16 сентября

  • Курс лекций В.В.Воеводина "Параллельная обработка данных"
  • Заморочки от Oracle, или знать бы, где упасть
  • Реинжиниринг: многое в малом
  • CASE-технологии: что, когда, как?

    14 сентября

  • Сильнее угроза - крепче защита (обзор 16 инструментов)
  • GnuPG - OpenSource шифрование и цифровые подписи
  • Оптимизация не-HTML-сайтов для поисковых серверов
  • Новые графические супер-карты от ATI и NVidia
  • Новая жизнь Ethernet

    9 сентября

  • Экстремальное программирование и быстрая разработка ПО
  • 64 бита - "народные" и не очень
  • Рынок ЖК-дисплеев: компании меняют приоритеты
  • Футбольный стадион на рабочем столе

    7 сентября

  • Методология оценки безопасности информационных технологий по общим критериям
  • MySQL Administrator - рулить СУБД легко
  • Взгляд на Windows через лупу
  • Все яйца в одном лукошке
  • Жесткие диски: любимая емкость

    2 сентября

  • Обзор внешних жестких дисков
  • Техника безопасности в беспроводном мире
  • Добавляем в компьютер USB
  • OpenGL и Delphi на практике
  • OpenGL: раскрой глаза на трехмерную графику
  • Иллюзии и реалии безопасности (обзор журнала Computer)

    31 августа

  • Ipsysctl tutorial 1.0.4
  • От включения питания до приглашения Bash
  • OpenBSD - заметки конечного пользователя
  • Запуск Linux-приложений из FreeBSD

    24 августа

  • О системных таблицах InterBase
  • О blog-ах замолвим пару словечек
  • Что такое RSS?
  • Разгон... Sound Blaster'а

    19 августа

  • Введение в Delphi 8
  • Парное тестирование - возьмем от ХР лучшее
  • XML-RPC: вызов процедур посредством XML
  • Связь и интернет для всей планеты
  • Сети для ловли будущего
  • Три кита будущей беспроводной свободы

    17 августа

  • Стеганография. Особенности использования программ на основе метода наименьшего значащего бита
  • Ping своими руками
  • Спецификации XML 1.1 и "Пространства имен 1.1"
  • Что нового в WSDL 2.0

    11 августа

  • Информационная безопасность в современных системах управления базами данных
  • Методические рекомендации №1 "О порядке автоматизации отчетности по МСФО"
  • Черводинамика: причины и следствия
  • Оживляем веб-страничку
  • Тихий ПК: несколько простых способов избавиться от компьютерного шума

    10 августа

  • Полезные советы по Windows XP
  • Oracle и Perl - это очень просто

    9 августа

  • Проблемы при восстановлении и их решение
  • Восстановление сервера с помощью onbar и ISM
  • Настройка диспетчера хранения данных ISM

    5 августа
    Виктор Костромин. "Linux для пользователя"

    Все новости >>>



  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware HOWTO

    Реклама на IT-портале citforum.ru

    Нестандартные PR-акции - pr@citforum.ru
    Пресс-релизы и информация в каталог компаний - manager@citforum.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2004 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.