How to extract variable from SOAP request in Edge policy? - apigee

Here's my policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="extract-operation">
<DisplayName>extract-operation</DisplayName>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<Source clearPayload="true">request.content</Source>
<VariablePrefix>apigee</VariablePrefix>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="soapenv">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
</Namespaces>
<Variable name="operation" type="string">
<XPath>/soapenv:Envelope/soapenv:Body</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
In trace tool I see that request.content resolves fine and shows the content, but I was expecting apigee.operation to be populated with the contents of . What am I doing wrong?
Fixed Policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="extract-operation">
<DisplayName>extract-operation</DisplayName>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<Source clearPayload="true">request.content</Source>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="soapenv">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
</Namespaces>
<Variable name="operation" type="nodeset">
<XPath>/soapenv:Envelope/soapenv:Body</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>

If you know the Xpath you don't really need the scema and then you take on more variable out of the equation (ie whether the schema is valid). Then you could just reference //Body (or wherever it is in the xml)

Related

Config Transform, Unrecognized XML Namespace After Transformation

One of our config files is being transformed oddly.
Base Config
<?xml version="1.0"?>
<configuration >
</configuration>
Release Config (as it is in the project, truncated for brevity)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore xdt:Transform="Insert">
<contentSearch>
<configuration>
<indexes>
<index id="sitecore_web_index">
<param desc="core" patch:instead="param[#desc='core']">#{IndexEnvironment}#_web_index</param>
</index>
</indexes>
<indexes role:require="Standalone or ContentManagement">
<index id="sitecore_master_index">
<param desc="core" patch:instead="param[#desc='core']">#{IndexEnvironment}#_master_index</param>
</index>
After a build is run, the output of the final config looks very strange:
Post build
<?xml version="1.0"?>
<configuration>
<sitecore>
<contentSearch>
<configuration>
<indexes>
<index id="sitecore_web_index">
<param desc="core" d7p1:instead="param[#desc='core']" xmlns:d7p1="http://www.sitecore.net/xmlconfig/">ASHQA_web_index</param>
</index>
</indexes>
<indexes d5p1:require="Standalone or ContentManagement" xmlns:d5p1="http://www.sitecore.net/xmlconfig/role/">
<index id="sitecore_master_index">
<param desc="core" d7p1:instead="param[#desc='core']" xmlns:d7p1="http://www.sitecore.net/xmlconfig/">ASHQA_master_index</param>
</index>
Notice how the patch and role definitions are changed to d7p1 and d5p1 respectively.
While this is valid XML, it is causing issues in our application which parses the XML and looks for the proper terms of patch and role.
TL;DR
Any namespaces required in a transformed config, need to be defined in the base config.
Base Config Updates
<?xml version="1.0"?>
<configuration xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
</configuration>
Even though the base config does not rely on these namespaces, they do not carry over properly if they are not included. This also cleans up the output of the resulting config as expected:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<contentSearch>
<configuration>
<indexes>
<index id="sitecore_web_index">
<param desc="core" patch:instead="param[#desc='core']">#{IndexEnvironment}#_web_index</param>
</index>
</indexes>
<indexes role:require="Standalone or ContentManagement">
<index id="sitecore_master_index">
<param desc="core" patch:instead="param[#desc='core']">#{IndexEnvironment}#_master_index</param>
</index>

Assign Message Policy does not work on Error responses

In Apigee, the Assign Message Policy only seems to work on successful responses. If the server responds with an error code, say, 403 Forbidden, the policy does not change the response. Is there any other way to modify error responses in Apigee.
This is my policy.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
<DisplayName>Assign Message-1</DisplayName>
<Properties/>
<Remove>
<Headers>
<Header name="Server"/>
</Headers>
</Remove>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
You can modify error responses in Apigee using FaultRules. You can take a look at Apigee's documentation about Fault handling .
The reason your AssignMessage policy is not executed is, that the error happens before your policy is being executed, thus being skipped.
You can either move your AssignMessage policy to be executed earlier in the flow or catch the error using fault handling logic and throw the error when you have executed all the desired logic.
In case of different response message of Success and Error,
I usually create 2 policy of Assign Message, one for Success and other for Error response.
Example of Success:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-ReturnSuccessResponse">
<DisplayName>AM-ReturnSuccessResponse</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
<Set>
<Payload contentType="application/json" variablePrefix="#" variableSuffix="#">
#resp.responseMessage#
</Payload>
<StatusCode>{resp.httpStatusCode}</StatusCode>
<ReasonPhrase>{resp.reasonPhrase}</ReasonPhrase>
</Set>
</AssignMessage>
Example of Error:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage async="false" continueOnError="false" enabled="true" name="AM-ReturnErrorResponse">
<DisplayName>AM-ReturnErrorResponse"</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
<Properties/>
<Set>
<Payload contentType="application/json" variablePrefix="#" variableSuffix="#">
{
"error" : "#resp.error#",
"timeStamp" : "#resp.responseDateTime#"
}
</Payload>
<StatusCode>{resp.httpStatusCode}</StatusCode>
<ReasonPhrase>{resp.reasonPhrase}</ReasonPhrase>
</Set> </AssignMessage>
And then in your flow you have to set condition for routing the policy like this
<Flow name="test">
<Description/>
<Request/>
<Response>
<Step>
<Name>AM-ReturnSuccessResponse</Name>
<Condition>resp.httpStatusCode == 200</Condition>
</Step>
<Step>
<Name>AM-ReturnErrorResponse</Name>
<Condition>resp.httpStatusCode != "200"</Condition>
</Step>
</Response>
</Flow>
Remark: Because normally http status code for success is 200, So I have set the condition like code above. But this is for example, you can design the condition up to your scenario.

Alfresco custom subtypes for cm:folder not working

I tried to to create a new folder type, that inherits everything from cm:folder, so I created an xml file for myModel.xml under tomcat/shared/classes/alfresco/extension/models, and added the following content to it:
<?xml version="1.0" encoding="UTF-8"?>
<!-- xsi:schemaLocation="http://www.alfresco.org/model/dictionary/1.0 modelSchema.xsd" -->
<model name="my:custmodel"
xmlns="http://www.alfresco.org/model/dictionary/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<description>custom folder test</description>
<author>Max Mustermann</author>
<published>2015-11-24</published>
<version>1.0</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
<namespace uri="http://www.alfresco.org/model/rendition/1.0" prefix="rn"/>
<namespace uri="http://www.alfresco.org/model/exif/1.0" prefix="exif"/>
<namespace uri="http://www.alfresco.org/model/audio/1.0" prefix="audio"/>
<namespace uri="http://www.alfresco.org/model/webdav/1.0" prefix="webdav"/>
<namespace uri="http://www.example.com/model/content/1.0" prefix="my" />
</namespaces>
<types>
<type name="my:folder1">
<title>folder1</title>
<parent>cm:folder</parent>
<archive>true</archive>
</type>
<type name="my:folder2">
<title>folder2</title>
<parent>cm:folder</parent>
<archive>true</archive>
</type>
</types>
then I added the following line to tomcat/shared/classes/alfresco/extension/custom-model-context.xml
<value>alfresco/extension/models/myModel.xml</value>
and finally in tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml:
<type name="cm:folder">
<subtype name="my:folder1" />
<subtype name="my:folder2" />
</type>
Now the under details->change Typ, my subtypes appear, but when I try to apply them I get "cannot change type of document ..."
Your model file name in context file is mentioned as
<value>alfresco/extension/models/custModel.xml</value>
in your description you are saying name as "myModel.xml" is that a typo? Otherwise your file entries looks okey. Hope you are placing those entries properly.
This entry
<namespace uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
should be part of <imports> tag not <namespaces>
Something like this
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
</imports>

Websphere - Set content type/charset of external resource

I have mapped static content (html) to external directory. When I request html file over HTTP, it returned content type/charset Windows-874.
Content-Type:text/html; charset=Windows-874
I would like to change it to
Content-Type:text/html; charset=UTF-8
How can I change it in 'ibm-web-ext.xml'? Or I have to change it in other configurations of Websphere?
Here is my ibm-web-ext.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-ext
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
version="1.0">
<file-serving-attribute name="extendedDocumentRoot" value="D:/XXX/content/" />
<reload-interval value="3"/>
<auto-encode-requests value="false"/>
<auto-encode-responses value="false"/>
<enable-directory-browsing value="false"/>
<enable-file-serving value="true"/>
<pre-compile-jsps value="false"/>
<enable-reloading value="true"/>
<enable-serving-servlets-by-class-name value="false" />
</web-ext>

How to replace attributes in XML transforms without the name attribute

I am using SlowCheetah to transform my Log4Net files when I publish. However, it can't seem to distinguish between the attributes in different appender sections.
My Log4Net.config looks basically like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="DevEmail" />
<from value="DevEmail" />
<subject value="Dev Warning" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="Time: %date%newlineHost: %property{log4net:HostName}%newlineClass: %logger%newlineUser: %property{user}%newlineMessage: %message%newline%newline%newline" />
</layout>
<threshold value="WARN" />
</appender>
<appender name="FatalSmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="DevEmail" />
<from value="DevEmail" />
<subject value="Dev Fatal" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="Time: %date%newlineHost: %property{log4net:HostName}%newlineClass: %logger%newlineUser: %property{user}%newlineMessage: %message%newline%newline%newline" />
</layout>
<threshold value="FATAL" />
</appender>
</log4net>
And my transform file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="ProductionEmail" xdt:Transform="SetAttributes" />
<from value="ProductionEmail" xdt:Transform="SetAttributes" />
<subject value="Production Warning" xdt:Transform="SetAttributes" />
</appender>
<appender name="FatalSmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="ProductionEmail" xdt:Transform="SetAttributes" />
<from value="ProductionEmail" xdt:Transform="SetAttributes" />
<subject value="Production Fatal" xdt:Transform="SetAttributes" />
</appender>
</log4net>
The problem is that the transformed config has the same subject attribute value for both appenders; I guess when it hits the SetAttributes it can't tell which tag it's looking for, so it transforms all of them. What it the correct syntax to tell it to only find the elements within the same appender? I assume I need to use the xdt:Locator attribute, but I can't do Match(name) like I do for web.config because these elements don't have a name attribute. The appender element has a name attribute, but I don't know how to tell it to match based on the parent element's name.
I know that I could use replace on the appender node, with the match(Name), but then I would be replacing the entire node, including a bunch of elements such as the layout which I don't want to be transformed (and thus have multiple copy-pastes of the same code, which I would like to avoid).
I found the answer in this MSDN article: http://msdn.microsoft.com/en-us/library/dd465326.aspx.
I needed to use xdt:Locator="Match(name)" on the parent <appender> node, and then xdt:Transform on the child nodes. I had tried this previously but had used xdt:locator="Match(name)" instead of xdt:Locator="Match(name)"... The attribute is case sensitive.

Resources