Nested policy что это значит
Перейти к содержимому

Nested policy что это значит

  • автор:

Что такое Feature Policy (Permissions-Policy)

Спецификация Feature Policy определяет механизм, который позволяет разработчикам выборочно включать и отключать использование различных возможностей браузера и API. Feature Policy — это экспериментальная технология со спецификацией выпуска 2019 года, поэтому она пока ещё имеет слабую поддержку браузерами.

Feature Policy похожа на Content Security Policy, но контролирует функции браузера вместо безопасности контента. Feature Policy содержит директивы, в которых указываются ключи и списки источников, ограничивающие использование возможностей этих директив.

Текущая спецификация в настоящее время имеет дело только с функциями, определёнными в объекте Documents, и пока не распространяется на Web Workers и Web Worklets (облегчённая версия Web Workers) .

Директивы Feature Policy

Текущий набор функций, контролируемых политикой, делится на две широкие категории:

Директивы обеспечение детального контроля над чувствительными или мощными функциями
accelerometer ambient-light-sensor autoplay camera display-capture document-domain
encrypted-media fullscreen focus-without-user-activation geolocation gyroscope magnetometer
microphone midi payment picture-in-picture publickey-credentials-get serial
screen-wake-lock speaker usb vibrate vr / xr-spatial-tracking wake-lock

Директивы применения лучших практик для хорошего пользовательского опыта (User Expirience)
document-access document-write execution-while-not-rendered execution-while-out-of-viewport font-display-late-swap
interest-cohort layout-animations lazyload legacy-image-formats loading-frame-default-eager
navigation-override oversized-images sync-script sync-xhr unoptimized-images
unoptimized-lossless-images unoptimized-lossless-images-strict unoptimized-lossy-images unsized-media vertical-scroll
web-share

Значания директив

Каждая функция, контролируемая политикой, имеет список разрешений по умолчанию (одно из ‘self’, ‘none’ или *), который определяет, разрешена ли функция в документе без объявленной Feature Policy в контексте просмотра верхнего уровня, а также автоматически ли делегируется доступ к этой функции документам во вложенных контекстах просмотра .

• Если директива не указана, используется её значения по умолчанию, во вложенных контекстах просмотра многие директивы отключены по-умолчанию.

• Если директива в атрибуте allow указана без ключей / списка разрешённых происхождений, в этом случае значением по умолчанию для списка разрешений является ‘src’ , который представляет источник URL в атрибуте src iframe (см пример).

• Ключи и происхождения родительского контекста просмотра наследуются во вложенные контексты просмотра, если последние не имеют собственных заголовка Feature Policy или атрибута allow .

Feature-Policy: geolocation ‘self’

и включение атрибута «allow» в элементе iframe:

<iframe src=»https://other.com/map» allow=»geolocation»></iframe>

выборочно включит геолокацию в этом фрейме перекрестного происхождения, но не в других, даже если они содержат документы с таким же происхождением (https://other.com/map).

Ключи или происхождения для директив контроля не оптимизированных изображений могут сопровождаться «значением» политики в скобках (value):

указывает максимальное значение 2, на которое картинки могут превышать размер относительно расчётного.

Ключевые слова для директив

В директивах Feature Policy могут использоваться специальные ключевые слова, которые представляют собой токены для обозначения некоторых специфичных происхождений (это другие токены, не имеющие ничего общего с их CSP-аналогами) :

‘self’ — функция/возможность браузера будет разрешена в этом документе и во всех вложенных контекстах просмотра, имеющих то же происхождение, что и родительский документ.

‘src’ — (только в атрибуте <iframe allow=’. ‘> ) в этом <iframe> возможность директивы будет разрешена, пока загруженный в ифрейм документ имеет то же происхождение, что и текущий URL-адрес в атрибуте src= ифрейма.

‘none’ — указанная возможность директивы отключена в контексте верхнего и вложенного просмотра.

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

Эти ключевые слова всегда интерпретируются в контексте во время синтаксического разбора, и в списке разрешений хранятся только те источники, на которые они ссылаются. Сами ключевые слова не являются частью списка разрешений.

Пример атрибута allow для YouTube видео в ифрейме:

<iframe allowfullscreen allow=»accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; camera ‘self’; microphone ‘none’; fullscreen *»>

* Атрибут allowfullscreen указан для браузеров, ещё не поддерживающих атрибут allow.

Список происхождений (origins) для директив
Объявление Feature Policy

Политика Feature Policy может быть доставлена в виде атрибута или в HTTP-заголовке Featuire-Policy.

Скрипты могут программно запрашивать информацию о текущей Feature Policy через объект FeaturePolicy, расположенный в document.featurePolicy или HTMLIFrameElement.featurePolicy (на октябрь 2019 свойство HTMLIMediaElement.featurePolicy не поддерживается, хотя сами теги <video> и <audio> поддерживают атрибут allow) .

Атрибут allow=

Атрибут allow используется для возможности применения Feature Policy непосредственно в виде атрибута тега <iframe>. Кроме тега <iframe> , атрибут allow может применяться и к другим тегам, например, <video> — см тест атрибута allow.

В атрибуте allow через ‘;‘ перечисляются «токены-директивы» возможностей (по аналогии с директивами CSP) , которым даётся разрешение на использование некоторых возможностей внутри ифрейма, например:

<iframe allow=»accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; camera ‘self’; microphone ‘none’; fullscreen *»>

HTTP-заголовок Feature-Policy

HTTP заголовок Feature-Policy предоставляет механизм, позволяющий и запрещающий использование функций браузера в своём собственном фрейме и в содержимом <iframe> , <video> , <audio> и другие элементы в документе, который поддерживает этот заголовок.

Синтаксис HTTP-заголовка Feature-Policy:

Feature-Policy: <directive> <allowlist>; <directive> <allowlist>

Feature-Policy: camera ‘none’; microphone ‘self’; picture-in-picture;

Интерфейсы document.featurePolicy и document.policy

The document.featurePolicy является доступным только для чтения свойством интерфейса document возвращает интерфейс FeaturePolicy, который предоставляет простой API для проверки политик функций, применённых к конкретному документу.

document.policy — ошибочное название свойства document.featurePolicy в некоторых версиях Google Chrome. (ссылка на BUG)

Интерфейс document.featurePolicy поддерживает методы:

featurePolicy.features() — метод интерфейса FeaturePolicy, возвращающий список имён всех возможностей/функций (features), поддерживаемых пользовательским агентом. Функция, имя которой отображается в списке, может быть запрещена политикой функций текущего контекста выполнения и / или может быть недоступна из-за разрешений пользователя.

const featurePolicy = document.featurePolicy; // Получить объект Feature Policy
const supportedDirectives = featurePolicy.features(); // Получить список всех поддерживаемых директив Feature Policy
for (const directive of supportedDirectives) < console.log(directive) >// Распечатать каждую директиву в консоли

featurePolicy.allowsFeature()allowsFeature(feature) это метод интерфейса FeaturePolicy позволяет проводить интроспекцию отдельных директив (feature) Feature Policy, в которой она выполняется. Он возвращает логическое значение, которое истинно тогда и только тогда, когда указанная функция разрешена в указанном контексте (или в контексте по умолчанию, если контекст не указан) .

featurePolicy.getAllowlistForFeature()getAllowlistForFeature(feature) метод получения разрешённых происхождений для заданного feature.

featurePolicy.allowedFeatures()allowedFeatures() это метод получения списка разрешённых в текущем контексте директив (features) Feature Policy.

Планируется внедрить в Feature Policy поддержку отчётов о нарушениях violation reports.

Передача ключей/происхождений из атрибутов allow и/или заголовков Feature-Policy во вложенные контексты просмотра

1. Если в родительском документе/ифрейме нет атрибута allow или заголовка FeaturePolicy, то во вложенных контекстах просмотра действуют значения по умолчанию, из родительского контекста ничего не передаётся.

2. Функция/возможность, не разрешённая в контексте верхнего уровня, не может быть разрешена атрибутом allow во вложенных контекстах просмотра.

3. Есть специфика передачи Feature Policy во вложенный контекст просмотра: при передаче списка разрешённых происхождений внутрь вложенного контекста просмотра, в него передаётся только одно конкретное происхождение, совпадающее с происхождением из атрибута src= или srcdoc= этого вложенного контекста просмотра.

Features API

Features/Permissions API обеспечивает согласованный программный способ запроса статуса Features API, относящихся к текущему контексту. Например, API Возможностей (Features API) можно использовать для определения, было ли предоставлено разрешение или запрещён доступ к определённой функции/возможности браузера.

Life As A Network Engineer – Rakesh

We were trying to suppress specific external routes into Routing-tables( Yes Tables, Juniper’s you see 😉 ). So in-order to achieve this wrote multiple policies for importing routes-into ospf. This created a sort of glitch? What was that Glitch and what is the final understanding of nested-policy we shall see.

new_3

Let us see the default policy on R2 Device and see what happens here.

I have this configuration of ospf on R2

[edit]
lab@mxb2# show protocols ospf | display set
set protocols ospf import o1
set protocols ospf import o2
set protocols ospf import o3
set protocols ospf area 0.0.0.0 interface ge-0/0/0.0

[edit]
lab@mxb2# show policy-options | display set
set policy-options policy-statement o1 term 1 from protocol ospf
set policy-options policy-statement o1 term 1 from route-filter 1.1.11.0/24 exact
set policy-options policy-statement o1 term 1 from route-filter 1.1.12.0/24 exact
set policy-options policy-statement o1 term 1 then accept
set policy-options policy-statement o1 term 2 then reject
set policy-options policy-statement o2 term 1 from route-filter 2.2.3.0/24 exact
set policy-options policy-statement o2 term 2 from route-filter 2.2.4.0/24 exact
set policy-options policy-statement o2 term 2 then accept
set policy-options policy-statement o3 term 1 from route-filter 2.2.1.0/24 exact
set policy-options policy-statement o3 term 1 from route-filter 2.2.2.0/24 exact
set policy-options policy-statement o3 term 1 then accept
set policy-options policy-statement o3 term 2 then reject

As we can see, there are three policies imported. Let us see how router process interprets this

i have included two routes 1.1.11.0/24 and 1.1.12.0/24 which are not present to math in o1 on purpose

Even though i have other two import policies in the protocol ospf, because of explicit reject there is a loopbreak, and hence it wont go for other policies in ospf

[edit]
lab@mxb2# run show route protocol ospf

inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, — = Last Active, * = Both

224.0.0.5/32 *[OSPF/10] 00:14:08, metric 1
MultiRecv

[edit]
lab@mxb2# run show ospf neighbor
Address Interface State ID Pri Dead
13.13.12.1 ge-0/0/0.0 Full 13.13.12.1 128 32

[edit]
lab@mxb2# run show ospf database

OSPF database, Area 0.0.0.0
Type ID Adv Rtr Seq Age Opt Cksum Len
Router 13.13.12.1 13.13.12.1 0x80000008 143 0x22 0xf19a 36
Router *13.13.12.2 13.13.12.2 0x80000007 142 0x22 0xeba0 36
Network *13.13.12.2 13.13.12.2 0x80000005 142 0x22 0x9501 32
OSPF AS SCOPE link state database
Type ID Adv Rtr Seq Age Opt Cksum Len
Extern 1.1.1.0 13.13.12.1 0x80000002 264 0x22 0xa2e4 36
Extern 1.1.2.0 13.13.12.1 0x80000001 870 0x22 0x99ed 36
Extern 1.1.3.0 13.13.12.1 0x80000001 870 0x22 0x8ef7 36
Extern 1.1.4.0 13.13.12.1 0x80000001 870 0x22 0x8302 36
Extern 2.2.0.0 13.13.12.1 0x80000001 870 0x22 0x96f0 36
Extern 2.2.1.0 13.13.12.1 0x80000001 870 0x22 0x8bfa 36
Extern 2.2.2.0 13.13.12.1 0x80000001 870 0x22 0x8005 36
Extern 2.2.3.0 13.13.12.1 0x80000001 870 0x22 0x750f 36

Now, lets tweak the policy and add another term which says for next policy

Now there is a change in the policy termination of first statement, instead of reject i have asked it to go to next-policy

set policy-options policy-statement o1 term 1 from protocol ospf
set policy-options policy-statement o1 term 1 from route-filter 1.1.11.0/24 exact
set policy-options policy-statement o1 term 1 from route-filter 1.1.12.0/24 exact
set policy-options policy-statement o1 term 1 then accept

set policy-options policy-statement o1 term 2 then next policy

set policy-options policy-statement o2 term 1 from route-filter 2.2.3.0/24 exact
set policy-options policy-statement o2 term 1 then accept
set policy-options policy-statement o2 term 2 from route-filter 2.2.4.0/24 exact
set policy-options policy-statement o2 term 2 then accept
set policy-options policy-statement o2 term 3 then reject
set policy-options policy-statement o3 term 1 from route-filter 2.2.1.0/24 exact
set policy-options policy-statement o3 term 1 from route-filter 2.2.2.0/24 exact
set policy-options policy-statement o3 term 1 then accept
set policy-options policy-statement o3 term 2 then reject

sure enough, the results are expected as we think

[edit]
lab@mxb2# run show route

inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, — = Last Active, * = Both

2.2.3.0/24 *[OSPF/150] 00:03:55, metric 0, tag 0
> to 13.13.12.1 via ge-0/0/0.0
2.2.4.0/24 *[OSPF/150] 00:03:09, metric 0, tag 0
> to 13.13.12.1 via ge-0/0/0.0
13.13.12.0/24 *[Direct/0] 04:05:29
> via ge-0/0/0.0
13.13.12.2/32 *[Local/0] 04:05:30
Local via ge-0/0/0.0
224.0.0.5/32 *[OSPF/10] 00:23:39, metric 1
MultiRecv

Now the Big question is What if i keep the policy as it is and now i will not import o2 policy into ospf

if that is the case, the o1 will not be a match but it will refer to o2 via term next policy.

[edit]
lab@mxb2# commit
commit complete

[edit]
lab@mxb2# run show route

inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, — = Last Active, * = Both

2.2.1.0/24 *[OSPF/150] 00:00:02, metric 0, tag 0
> to 13.13.12.1 via ge-0/0/0.0
2.2.2.0/24 *[OSPF/150] 00:00:02, metric 0, tag 0
> to 13.13.12.1 via ge-0/0/0.0
13.13.12.0/24 *[Direct/0] 04:07:05
> via ge-0/0/0.0
13.13.12.2/32 *[Local/0] 04:07:06
Local via ge-0/0/0.0
224.0.0.5/32 *[OSPF/10] 00:25:15, metric 1
MultiRecv

as we can see, the import policy here in next policy chain will be overridden by the import policy which we give in protocol.

As in this case , even though policy options have o1 o2 and o3 and o1 has next-policy as a terminating action, if that is not imported into ospf or for that matter if not kept in proper import order, it will skip to next policy in OSPF but not in policy chain

Понимание WS-Policy, часть I: структура политики и составные политики

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

Следующая статья является отрывком из новой книги «Разработка контрактов веб-сервисов и управление версиями для SOA» [REF-1] Авторские права Prentice Hall / Pearson PTR и SOA Systems Inc. Обратите внимание, что некоторые ссылки на главы были намеренно оставлены в статье в соответствии с требования от Prentice Hall.

Эта статья написана Умитом Ялкинальпом и Томасом Эрлом и опубликована в журнале SOA в феврале 2009 г.

Введение
Существует множество видов политик, некоторые из которых предварительно определены отраслевыми спецификациями, а другие могут быть настроены разработчиком контракта веб-службы. Например, вы можете использовать политики для выражения функциональной совместимости и ограничений протокола, а также требований конфиденциальности, управляемости и качества обслуживания (QoS). Кроме того, политики могут быть созданы для одной стороны, или они могут применяться к многопартийным взаимодействиям.

С точки зрения архитектурного и контрактного дизайна, политики влияют на все уровни дизайна сервиса. Их можно применять к большинству частей абстрактных и конкретных описаний документа WSDL, и их можно применять в разных областях. Например, одна политика может относиться к определению сообщения, а другая применяется ко всему типу порта WSDL (или интерфейсу).

В этой статье мы сначала рассмотрим основные аспекты политик, а затем познакомим вас с основными частями языка WS-Policy. В главах 16 и 17 продолжено изучение структуры WS-Policy путем документирования ряда расширенных языковых функций и методов проектирования.

Языки XML Schema и WSDL позволяют нам делать чуть больше, чем выражать требования взаимодействия и ограничения веб-службы. Хотя для нас, конечно, принципиально важно делать что-то полезное с веб-сервисом, он не дает нам возможности описать другие аспекты веб-сервиса, такие как:

Существуют ли определенные требования QoS (надежность, безопасность и т. Д.), Которые потребуются пользовательским программам для работы с сервисом?
Существуют ли какие-либо дополнительные требования относительно того, как услуга может или не может быть доступна?
Существуют ли свойства или характеристики сервиса, которые могут представлять интерес для потребительских программ?
Существуют ли определенные правила, которые необходимо соблюдать для взаимодействия с сервисом?

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

Прежде чем мы узнаем больше об отдельных элементах языка WS-Policy, давайте сначала введем некоторую базовую терминологию:

Формальный термин для политики — выражение политики .
Выражение политики может состоять из одного или нескольких элементов, которые выражают конкретные требования или свойства политики. Каждый из них называется политическим утверждением .
Чтобы сгруппировать утверждения политики, мы используем набор функций из языка WS-Policy, известных как операторы политики .
Выражения политики по желанию могут быть выделены в отдельный документ, называемый определением WS-Policy .

Среди всех этих частей структуры WS-Policy самым основным строительным блоком является утверждение политики.

Новые пространства имен и префиксы

Теперь давайте уделим минуту, чтобы установить некоторые новые пространства имен и префиксы, связанные с языком WS-Policy и общими политиками:

xmlns: wsp = «http://www.w3.org/2006/07/ws-policy» — представляет фактическое пространство имен, используемое для элементов языка WS-Policy.
xmlns: wsam = «http://www.w3.org/2007/05/addressing/metadata». Мы покажем несколько примеров политики, относящихся к языку WS-Addressing, поэтому здесь возникает это пространство имен. Как на самом деле работают упомянутые функции WS-Addressing, описано в Главе 18, и это конкретное утверждение политики далее рассматривается в конце Главы 19.
xmlns: wsrmp = «http://docs.oasis-open.org/ws-rx/wsrmp/200702» — это пространство имен соответствует утверждению политики WS-ReliableMessaging. Хотя WS-ReliableMessaging не является технологией, описанной в этой книге, в примерах есть несколько ссылок на одно из его утверждений политики.
xmlns: wsu = «http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd» — существует специальный тип схемы, который называется «служебная схема», в которой устанавливаются общие и часто используемые атрибуты. Одним из таких атрибутов является wsu: Id , простой идентификатор, используемый для связи идентификатора с элементом. Эта и другие главы иногда ссылаются на этот атрибут.

Обратите внимание, что в примерах, приведенных в примерах, мы обычно избегаем отображения ранее перечисленных значений xmlns просто для того, чтобы избежать повторного беспорядка фрагментов кода определения политики.

Утверждения, выражения и элемент политики
Самое важное, что нужно понять о WS-Policy, — это то, что это не технология или язык, используемый для реализации политик. Его единственная цель — предоставить стандартизированный синтаксис для выражения политик (отсюда и термин «выражение политики»).
Утверждения политики

Все начинается с утверждения политики, которое само по себе является просто ссылкой на предопределенный глобальный элемент XML-схемы.

Вот пример простого утверждения политики:

Элемент wsrmp: RMAssertion ссылается на элемент расширяемости, определенный в спецификации WS-ReliableMessaging. Поэтому это считается утверждением политики WS-ReliableMessaging.

Схема XML, которая определяет это утверждение, выглядит следующим образом:

Мы называем то, что определено в этой схеме, типом политики . Каждое утверждение имеет базовый тип политики, который может быть предоставлен отраслевым стандартом, таким как WS-Reliable-Messaging, или вы можете настроить его, создав собственную схему. Все, что вам нужно, это глобальный элемент, на который можно ссылаться в синтаксисе утверждения политики.

Помимо предоставления стандартизированного выражения политики, WS-Policy не имеет ничего общего с тем, как на самом деле обрабатываются утверждения политики. Например, то, что происходит, когда элемент wsrmp: RMAssertion встречается во время выполнения, зависит от процессоров, связанных с WS-ReliableMessaging. Все, для чего мы используем WS-Policy, это связать это утверждение с определением WSDL.

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

Мы собираемся использовать элемент wsrmp: RMAssertion во всех главах WS-Policy. Давайте теперь посмотрим на другой пример:

WS-Addressing предоставляет предопределенный элемент расширяемости wsam: Addressing, который можно использовать в конструкции привязки WSDL для связи WS-Addressing с веб-службой.

Как и в случае с wsrmp: RMAssertion , это утверждение вводит требование, чтобы входящие сообщения поддерживали определенную технологию; в этом случае WS-Addressing.

Выражения политики Сами по

себе предыдущие утверждения политики еще не существуют как отдельные политики. Чтобы создать фактическое выражение политики , нам нужно заключить утверждения в конструкцию wsp: Policy следующим образом:

Custom Policy Assertions

Let’s now assume you want to create you own policy expression with an assertion that defines a response guarantee for a particular operation. Let’s first create the XML Schema element that forms the basis of the required policy assertion.

This is a good example of a custom-created QoS policy that can be added to a service contract so that consumers could retrieve the number of milliseconds within which the service promises to perform a particular task.

If you recall the ActionCon Purchase Order service, an assertion such as this could be used to indicate the amount of time the service will take to generate and return a purchase order document. Depending on the circumstances, the actual value of the assertion may differ, as shown in the following two assertion instances.tax.

Assertion Instance #1

Assertion Instance #2

Both assertions have the same assertion element, namely argt:responseGuarantee . However, each instance has a different value.

Composite Policies
In the previous example we created a simple policy assertion. On its own, this one assertion may be sufficient to warrant an entire, self-contained policy expression. However, more often than not, policies need to be assembled out of multiple policy assertions.

In order to combine policy assertion constructs into composite policy expressions, we need to use a new feature of the WS-Policy language known as operators. Specifically, we will need to work with the wsp:ExactlyOne and wsp:All elements and the wsp:optional attribute.

The ExactlyOne Element

This element groups a set of policy assertions from which only one can be used. In other words, it enforces a rule that «exactly one» of the listed assertions must be chosen.

Using the wsp:ExactlyOne element introduces the concept of policy alternatives as part of a policy expression. Each child element within this construct is considered a distinct alternative in the overall policy expression.

Consider the following example:

Here, the WS-Policy expression contains two distinct alternatives. Each assertion, wsam:Addressing and wsrmp:RMAssertion , indicates a separate alternative.
The wsp:All Element

The wsp:All operator element is the reverse of the wsp:ExactlyOne element. It imposes a rule that requires that all of the assertions within its construct be applied at the same time.

If we restructure the previous example using this element, it actually looks quite similar.

As with the wsp:ExactlyOne construct, it does not matter in what order you decide to place the policy assertion type elements.

The wsp:optional Attribute

The WS-Policy language provides a special Boolean attribute named wsp:optional that allows you to indicate that a policy assertion is not mandatory.

The following example shows this attribute used in conjunction with our previous wsam:Addressing assertion:

This attribute is considered a «shortcut» because you can express the same policy logic in a more verbose manner using the previously described operator elements. The wsp:All element is essentially the same as specifying two distinct alternatives in a policy expression, as follows:

In this example, we have a wsp:ExactlyOne construct that houses two wsp:All elements. The second wsp:All element is highlighted. Unlike the first, which establishes a construct with one assertion, this second wsp:All element is empty.

According to the «exactly one» rule, we must choose one of the two alternatives. The first alternative is that the wsam:Addressing assertion is used because in this alternative, the assertion is wrapped in a nested wsp:All construct. The second alternative is that the second wsp:All element be chosen, and because it is empty, the result of this choice is that nothing happens. In other words, the use of the policy assertion is optional, as with the previous example that used the wsp:optional attribute. This last example also hints at the more complex structures that can be built using nested operator elements and various other combinations, as described further in the next section.

Conclusion
Part II of this article series will focus on operator composition rules and techniques for attaching policies to WSDL documents.

Как реляционная СУБД делает JOIN?

С SQL работают почти все, но даже опытные разработчики иногда не могут ответить на простой вопрос. Каким образом СУБД выполняет самый обычный INNER JOIN?

С другой стороны — разработчики на C# или других ООП языках часто воспринимают СУБД как всего лишь хранилище. И размещать какие-то бизнес-правила в SQL — плохо. В противовес им создаются библиотеки вроде Linq2Db (не путаем с Linq2Sql — совершенно разные авторы и разные библиотеки). При ее использовании весь код пишется на C# и вы получаете все преимущества типизированного языка. Но это формальность. Затем этот код транслируется на SQL и выполняется на стороне СУБД.

Для того чтобы лучше разобраться как работает одинаковый код на SQL и на C# мы попробуем реализовать одно и то же на первом и на втором, а затем разберем как это работает. Если вы хорошо знаете что такое Nested Loop, Merge Join, Hash Join — вам скорее всего имеет смысл прочитать статью по диагонали. А вот если не знаете — статья для вас должна быть полезной.

Работа с несколькими коллекциями

Предположим, что у нас есть некоторый сервисный центр по техническому обслуживанию автомобилей — станция технического обслуживания (СТО). Есть две сущности: Person — клиенты сервисного центра и Visit — конкретное посещение данного центра. Person кроме идентификатора содержит имя, фамилию и статус активности (например, если клиент поменял машину на другую марку — он переводится в статус не активного и уже не будет в ближайшем времени посещать нас). Visit кроме идентификатора содержит в себе ссылку на клиента, дату визита и сумму, которую заплатил клиент за этот визит. Все вышеперечисленное можно было бы оформить с помощью следующих классов на C# для самого простейшего случая:

В базе данных (в дальнейшем мы будем использовать PostgreSQL) для двух этих сущностей есть две таблицы с аналогичными полями:

Исходный код для данной статьи находится здесь. Если у вас есть какие-то замечания — можете сразу править.

Пусть наша задача сводится к написанию простейшего бизнес-правила — найти общую сумму выручки за 2020 год и ранее, которую принесли клиенты, находящиеся сейчас в активном статусе. Как можно реализовать решение такой простой задачи?

Nested Loop

Самая простая идея, которая приходит на ум. Бежим в цикле по клиентам и во вложенном цикле бежим по всем посещениям. Проверяем все условия и если находим совпадение — добавляем сумму затрат этого визита в итоговый результат.

Эта идея анимирована ниже:

Алгоритм очень простой, не потребляет дополнительной памяти. Но затратность его O(N²), что будет сказываться на большом числе элементов — чем их больше, тем больше телодвижений необходимо совершить.

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

В данном случае число клиентов CTO P равно 5000, число их визитов V — 10000. Дата визита, а также сам факт визита для клиента генерируются случайным образом из указанных диапазонов. Признак активности клиента выставляется для каждого пятого. В итоге мы получаем некоторый тестовый набор данных, приближенный к реальному. Для тестового набора нам интересна характеристика — число клиентов и посещений. Или (P,V) равное в нашем случае (5000, 10000). Для этого тестового набора мы сделаем следующее: выгрузим его в обьекты C# и с помощью цикла в цикле (Nested Loop) посчитаем суммарные траты наших посетителей. Как это определено в постановке задачи. На моем компьютере получаем приблизительно 20.040 миллисекунд, затраченное на подсчет. При этом время получение данных из БД составило все те же самые 20.27 миллисекунд. Что в сумме дает около 40 миллисекунд. Посмотрим на время выполнения SQL запроса на тех же данных.

Все на том же компьютере получилось порядка 2.1 миллисекунды на все. И кода заметно меньше. Т.е. в 10 раз быстрее самого метода, не считая логики по извлечению данных из БД и их материализации на стороне приложения.

Merge Join

Разница в скорости работы в 20 раз наталкивает на размышления. Скорее всего Nested Loop не очень нам подходити мы должны найти что-то получше. И есть такой алгоритм… Называется Merge Join или Sort-Merge Join. Общая суть в том, что мы сортируем два списка по ключу на основе которого происходит соединение. И делаем проход всего в один цикл. Инкрементируем индекс и если значения в двух списках совпали — добавляем их в результат. Если в левом списке идентификатор больше, чем в правом — увеличиваем индекс массива только для правой части. Если, наоборот, в левом списке идентификатор меньше, то увеличиваем индекс левого массива. Затратность такого алгоритма O(N*log(N)).

Результат работы такой реализации радует глаз — 1.4 миллисекунды в C#. Правда данные из базы данных еще нужно извлечь. А это все те же самые дополнительные 20 миллисекунд. Но если вы извлекаете данные из БД, а затем выполняете несколько обработок, то недостаток постепенно нивелируется. Но можно ли подсчитать заданную сумму еще быстрее? Можно! Hash Join поможет нам в этом.

Hash Join

Этот алгоритм подходит для больших массивов данных. Его идея проста. Для каждого из списков считается хэш ключа, далее этот хэш используется для того, чтобы выполнить сам Join. Детально можно посмотреть в видео:

Затратность алгоритма O(N). В .NET стандартный Linq метод как раз его и реализует. В реляционных СУБД часто используются модификации этого алгоритма (Grace hash join, Hybrid hash join) — суть которых сводится к работе в условиях ограниченной оперативной памяти. Замер скорости работы в C# показывает, что этот алгоритм еще быстрее и выполняется за 0.9 миллисекунды.

Динамический выбор алгоритма

Отлично! Похоже мы нашли универсальный алгоритм, который самый быстрый. Нужно просто использовать его всегда и не беспокоиться более об этом вопросе. Но если мы учтем еще и расход памяти все станет немного сложнее. Для Nested Loop — память не нужна, Merge Join — нужна только для сортировки (если она будет). Для Hash Join — нужна оперативная память.

Оказывается расход памяти — это еще не все. В зависимости от общего числа элементов в массивах скорость работы разных алгоритмов ведет себя по-разному. Проверим для меньшего числа элементов (P, V) равному (50, 100). И ситуация переворачивается на диаметрально противоположную: Nested Loop самый быстрый — 2.202 микросекунды, Merge Join — 4.715 микросекунды, Hash Join — 7.638 микросекунды. Зависимость скорости работы каждого алгоритма можно представить таким графиком:

Для нашего примера можно провести серию экспериментов на C# и получить следующую таблицу:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *