Я нашел решение этого.
Вот сценарий: у меня есть требование, чтобы клиент вызвал конечную точку APIM и получил только простые ответы. т.е. .... аутентифицированный = истина / ложь.
У меня есть входящий запрос GET от системы, которая может отправлять ТОЛЬКО запросы GET. Моей внутренней службе требуется запрос POST.
Вот мой вызов GET от клиента, который может отправлять только запросы GET: https: /// api / v1 // 10010810? Pin = 1212 & property = Sydney & subscription-key = XXXXXXXXXXXXXX & debugging = 1
Вот моя политика:
<policies>
<inbound>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<trace source="defaultTrace">
@{
return System.String.Format("The passed in querystring paramters were | pin: {0} | debugging: {1} | property: {2} | subscription-key: {3}",
context.Request.Url.Query.GetValueOrDefault("pin"),
context.Request.Url.Query.GetValueOrDefault("debugging"),
context.Request.Url.Query.GetValueOrDefault("property"),
context.Request.Url.Query.GetValueOrDefault("subscription-key")
);
}
</trace>
<set-variable name="requestPin" value="@(context.Request.Url.Query.GetValueOrDefault("pin"))" />
<set-variable name="debugging" value="@(context.Request.Url.Query.GetValueOrDefault("debugging"))" />
<trace source="defaultTrace">
@{
return System.String.Format(
"Removing the following querystring parameters from url as we don't want to pass these ones to the backend service debugging: {0} | subscription-key: {1} | pin: {2}",
context.Request.Url.Query.GetValueOrDefault("debugging"),
context.Request.Url.Query.GetValueOrDefault("subscription-key"),
context.Request.Url.Query.GetValueOrDefault("pin")
);
}
</trace>
<set-query-parameter name="subscription-key" exists-action="delete" />
<set-query-parameter name="debugging" exists-action="delete" />
<set-query-parameter name="pin" exists-action="delete" />
<base />
</inbound>
<backend>
<!-- Setup a response-variable-name to hold the response from the backend service-->
<send-request mode="copy" response-variable-name="microservice-response" timeout="20" ignore-error="false">
<!-- Set the method to POST as the backend service MUST receive a POST call-->
<set-method>POST</set-method>
<set-body>
@{
// Get the pin from the url as we need it to construct the POST body
var requestPin = context.Variables.GetValueOrDefault<string>("requestPin");
var postBody = new JObject(
new JProperty("Type", "Pin"),
new JProperty("Value", requestPin)
).ToString();
return postBody;
}
</set-body>
</send-request>
</backend>
<outbound>
<choose>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 200)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="200" reason="Ok" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]).Body.As<JObject>();
if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", true),
new JProperty("MicroserviceResponse", microserviceResponse),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", true)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 401)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="401" reason="Error" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);
if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 400)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="200" reason="Ok" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);
if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<otherwise>
<return-response>
<!-- When the micro-service threw an exception we just want to show the caller Authenticated = false -->
<!--<set-status code="500" reason="Error" />-->
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);
if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</otherwise>
</choose>
<base />
</outbound>
<on-error>
<!-- When APIM threw an exception -->
<trace source="defaultTrace">
@{
var returnResponse = new JObject
(
new JProperty("Authenticated", false),
new JProperty("Source", context.LastError.Source),
new JProperty("Reason", context.LastError.Reason),
new JProperty("Message", context.LastError.Message),
new JProperty("Scope", context.LastError.Scope),
new JProperty("Section", context.LastError.Section),
new JProperty("Path", context.LastError.Path),
new JProperty("PolicyId", context.LastError.PolicyId)
).ToString();
return returnResponse.ToString();
}
</trace>
<return-response>
<set-status code="500" reason="Error" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
if(debuggingVariable == "1")
{
var returnResponse = new JObject
(
new JProperty("Authenticated", false),
new JProperty("Source", context.LastError.Source),
new JProperty("Reason", context.LastError.Reason),
new JProperty("Message", context.LastError.Message),
new JProperty("Scope", context.LastError.Scope),
new JProperty("Section", context.LastError.Section),
new JProperty("Path", context.LastError.Path),
new JProperty("PolicyId", context.LastError.PolicyId)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</on-error>
The policy does the following:
В РАМКАХ
- Записывает некоторые операторы трассировки повсюду
- Получает пару параметров из строки запроса для использования в политике.
- Удаляет пару параметров, поскольку мы не можем передать их в серверную службу, поскольку вызов не будет соответствовать сигнатуре метода.
BACK-END - Отправить запрос
- Отправляет запрос в серверную службу, используя существующий URL-адрес, который был передан, но, очевидно, без параметров, которые мы удалили
- Устанавливает метод POST
- Устанавливает тело сообщения с помощью другого параметра
ВНЕЗАПНО
- Если мы получили ответ 200, значит, мы знаем, что серверная служба работает правильно.
- Настройте переменную под названием microservice-response для хранения ответа от серверной службы.
- Установите переменную отладки, которая будет удалена в процессе производства. Это сделано для того, чтобы тестеры могли получить более подробную информацию. Мы отобразим им содержимое микросервиса-ответа.
- Если что-то пошло не так с серверной службой (не ответ 200), то выдает ошибку
ПРИ ОШИБКЕ
- Когда APIM фиксирует ошибку. Извлеките все детали из переменной context.LastError, и если в режиме отладки, то отправьте вызывающему
Вот пример context.LastError:
Я надеюсь, что это поможет кому-то, так как мне потребовалось много времени, чтобы добраться до этого момента. Документация по этому поводу хороша, но там не так много
person
RuSs
schedule
22.11.2016