Initial commit
This commit is contained in:
381
templates/api-policy-template.xml
Normal file
381
templates/api-policy-template.xml
Normal file
@@ -0,0 +1,381 @@
|
||||
<!--
|
||||
SAP API Management - Policy Template
|
||||
|
||||
Usage: Use these templates as starting points for API policies
|
||||
|
||||
Documentation:
|
||||
- Policies: https://github.com/SAP-docs/sap-btp-integration-suite/blob/main/docs/apim/API-Management/policies-7e4f3e5.md
|
||||
- Policy Types: https://github.com/SAP-docs/sap-btp-integration-suite/blob/main/docs/apim/API-Management/policy-types-c918e28.md
|
||||
-->
|
||||
|
||||
<!-- ========================================
|
||||
SECURITY POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- Verify API Key -->
|
||||
<!--
|
||||
<VerifyAPIKey name="Verify-API-Key" enabled="true" continueOnError="false">
|
||||
<APIKey ref="request.header.x-api-key"/>
|
||||
[Alternative: use query parameter instead]
|
||||
[<APIKey ref="request.queryparam.apikey"/>]
|
||||
</VerifyAPIKey>
|
||||
-->
|
||||
|
||||
<!-- OAuth 2.0 Token Validation -->
|
||||
<!--
|
||||
<OAuthV2 name="Validate-OAuth-Token" enabled="true">
|
||||
<Operation>VerifyAccessToken</Operation>
|
||||
<AccessToken ref="request.header.Authorization"/>
|
||||
<Scope>read write</Scope>
|
||||
</OAuthV2>
|
||||
-->
|
||||
|
||||
<!-- Basic Authentication -->
|
||||
<!--
|
||||
<BasicAuthentication name="Decode-Basic-Auth" enabled="true">
|
||||
<Operation>Decode</Operation>
|
||||
<User ref="request.header.username"/>
|
||||
<Password ref="request.header.password"/>
|
||||
<Source>request.header.Authorization</Source>
|
||||
</BasicAuthentication>
|
||||
-->
|
||||
|
||||
<!-- Access Control (IP Whitelist) -->
|
||||
<!--
|
||||
<AccessControl name="IP-Whitelist" enabled="true">
|
||||
<IPRules noRuleMatchAction="DENY">
|
||||
<MatchRule action="ALLOW">
|
||||
<SourceAddress mask="24">192.168.1.0</SourceAddress>
|
||||
</MatchRule>
|
||||
<MatchRule action="ALLOW">
|
||||
<SourceAddress mask="32">10.0.0.1</SourceAddress>
|
||||
</MatchRule>
|
||||
</IPRules>
|
||||
</AccessControl>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
TRAFFIC MANAGEMENT POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- Quota (Rate Limiting) -->
|
||||
<!--
|
||||
<Quota name="Check-Quota" enabled="true" continueOnError="false">
|
||||
<Allow count="1000"/>
|
||||
<Interval>1</Interval>
|
||||
<TimeUnit>month</TimeUnit>
|
||||
<Identifier ref="request.header.x-api-key"/>
|
||||
<MessageWeight ref="request.header.weight"/>
|
||||
</Quota>
|
||||
-->
|
||||
|
||||
<!-- Spike Arrest (Prevent Traffic Spikes) -->
|
||||
<!--
|
||||
<SpikeArrest name="Spike-Control" enabled="true">
|
||||
<Rate>30pm</Rate>
|
||||
[Alternative: per second]
|
||||
[<Rate>10ps</Rate>]
|
||||
<Identifier ref="request.header.x-api-key"/>
|
||||
</SpikeArrest>
|
||||
-->
|
||||
|
||||
<!-- Response Cache -->
|
||||
<!--
|
||||
<ResponseCache name="Cache-Response" enabled="true">
|
||||
<CacheKey>
|
||||
<Prefix>myapi</Prefix>
|
||||
<KeyFragment ref="request.uri"/>
|
||||
<KeyFragment ref="request.queryparam.format"/>
|
||||
</CacheKey>
|
||||
<ExpirySettings>
|
||||
<TimeoutInSec>3600</TimeoutInSec>
|
||||
</ExpirySettings>
|
||||
<CacheResource>default</CacheResource>
|
||||
</ResponseCache>
|
||||
-->
|
||||
|
||||
<!-- Lookup Cache -->
|
||||
<!--
|
||||
<LookupCache name="Lookup-Cached-Data" enabled="true">
|
||||
<CacheKey>
|
||||
<Prefix>mydata</Prefix>
|
||||
<KeyFragment ref="request.queryparam.id"/>
|
||||
</CacheKey>
|
||||
<Scope>Exclusive</Scope>
|
||||
<CacheResource>default</CacheResource>
|
||||
<AssignTo>cachedValue</AssignTo>
|
||||
</LookupCache>
|
||||
-->
|
||||
|
||||
<!-- Populate Cache -->
|
||||
<!--
|
||||
<PopulateCache name="Store-In-Cache" enabled="true">
|
||||
<CacheKey>
|
||||
<Prefix>mydata</Prefix>
|
||||
<KeyFragment ref="request.queryparam.id"/>
|
||||
</CacheKey>
|
||||
<Scope>Exclusive</Scope>
|
||||
<CacheResource>default</CacheResource>
|
||||
<Source>response.content</Source>
|
||||
<ExpirySettings>
|
||||
<TimeoutInSec>300</TimeoutInSec>
|
||||
</ExpirySettings>
|
||||
</PopulateCache>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
MEDIATION POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- Assign Message (Set Headers/Payload) -->
|
||||
<!--
|
||||
<AssignMessage name="Set-Headers" enabled="true">
|
||||
<AssignTo createNew="false" transport="http" type="request"/>
|
||||
<Set>
|
||||
<Headers>
|
||||
<Header name="X-Forwarded-For">{client.ip}</Header>
|
||||
<Header name="X-Request-ID">{messageid}</Header>
|
||||
</Headers>
|
||||
</Set>
|
||||
<Add>
|
||||
<QueryParams>
|
||||
<QueryParam name="format">json</QueryParam>
|
||||
</QueryParams>
|
||||
</Add>
|
||||
<Remove>
|
||||
<Headers>
|
||||
<Header name="X-Internal-Header"/>
|
||||
</Headers>
|
||||
</Remove>
|
||||
</AssignMessage>
|
||||
-->
|
||||
|
||||
<!-- Extract Variables -->
|
||||
<!--
|
||||
<ExtractVariables name="Extract-Data" enabled="true">
|
||||
<Source>request</Source>
|
||||
<!-- From JSON payload -->
|
||||
<JSONPayload>
|
||||
<Variable name="userId" type="string">
|
||||
<JSONPath>$.user.id</JSONPath>
|
||||
</Variable>
|
||||
<Variable name="orderCount" type="integer">
|
||||
<JSONPath>$.orders.length()</JSONPath>
|
||||
</Variable>
|
||||
</JSONPayload>
|
||||
<!-- From XML payload -->
|
||||
<XMLPayload stopPayloadProcessing="false">
|
||||
<Namespaces>
|
||||
<Namespace prefix="ns">http://example.com/ns</Namespace>
|
||||
</Namespaces>
|
||||
<Variable name="orderId" type="string">
|
||||
<XPath>/ns:Order/ns:OrderId</XPath>
|
||||
</Variable>
|
||||
</XMLPayload>
|
||||
<!-- From headers/query params -->
|
||||
<Header name="Content-Type">
|
||||
<Pattern ignoreCase="true">application/{format}</Pattern>
|
||||
</Header>
|
||||
<QueryParam name="id">
|
||||
<Pattern>{entityId}</Pattern>
|
||||
</QueryParam>
|
||||
</ExtractVariables>
|
||||
-->
|
||||
|
||||
<!-- JSON to XML Conversion -->
|
||||
<!--
|
||||
<JSONToXML name="Convert-JSON-to-XML" enabled="true">
|
||||
<Source>request</Source>
|
||||
<OutputVariable>request.content</OutputVariable>
|
||||
<Options>
|
||||
<NullValue>NULL</NullValue>
|
||||
<NamespaceBlockName>#namespaces</NamespaceBlockName>
|
||||
<DefaultNamespaceNodeName>&</DefaultNamespaceNodeName>
|
||||
<NamespaceSeparator>:</NamespaceSeparator>
|
||||
<TextNodeName>#text</TextNodeName>
|
||||
<AttributeBlockName>#attrs</AttributeBlockName>
|
||||
<AttributePrefix>@</AttributePrefix>
|
||||
<InvalidCharsReplacement>_</InvalidCharsReplacement>
|
||||
<ObjectRootElementName>root</ObjectRootElementName>
|
||||
<ArrayRootElementName>root</ArrayRootElementName>
|
||||
<ArrayItemElementName>item</ArrayItemElementName>
|
||||
</Options>
|
||||
</JSONToXML>
|
||||
-->
|
||||
|
||||
<!-- XML to JSON Conversion -->
|
||||
<!--
|
||||
<XMLToJSON name="Convert-XML-to-JSON" enabled="true">
|
||||
<Source>response</Source>
|
||||
<OutputVariable>response.content</OutputVariable>
|
||||
<Options>
|
||||
<NullValue>NULL</NullValue>
|
||||
<NamespaceBlockName>#namespaces</NamespaceBlockName>
|
||||
<DefaultNamespaceNodeName>&</DefaultNamespaceNodeName>
|
||||
<NamespaceSeparator>:</NamespaceSeparator>
|
||||
<TextNodeName>#text</TextNodeName>
|
||||
<AttributeBlockName>#attrs</AttributeBlockName>
|
||||
<AttributePrefix>@</AttributePrefix>
|
||||
<OutputPrefix></OutputPrefix>
|
||||
<OutputSuffix></OutputSuffix>
|
||||
<StripLevels>0</StripLevels>
|
||||
<TreatAsArray>
|
||||
<Path>/root/items/item</Path>
|
||||
</TreatAsArray>
|
||||
</Options>
|
||||
</XMLToJSON>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
EXTENSION POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- JavaScript Policy -->
|
||||
<!--
|
||||
<Javascript name="Custom-Logic" enabled="true" timeLimit="200">
|
||||
<ResourceURL>jsc://custom-script.js</ResourceURL>
|
||||
<IncludeURL>jsc://utils.js</IncludeURL>
|
||||
</Javascript>
|
||||
-->
|
||||
|
||||
<!-- Service Callout -->
|
||||
<!--
|
||||
<ServiceCallout name="Call-External-Service" enabled="true">
|
||||
<Request clearPayload="true" variable="calloutRequest">
|
||||
<Set>
|
||||
<Verb>GET</Verb>
|
||||
<Path>/api/data</Path>
|
||||
</Set>
|
||||
</Request>
|
||||
<Response>calloutResponse</Response>
|
||||
<HTTPTargetConnection>
|
||||
<URL>https://api.example.com</URL>
|
||||
<SSLInfo>
|
||||
<Enabled>true</Enabled>
|
||||
</SSLInfo>
|
||||
</HTTPTargetConnection>
|
||||
<Timeout>30000</Timeout>
|
||||
</ServiceCallout>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
THREAT PROTECTION POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- JSON Threat Protection -->
|
||||
<!--
|
||||
<JSONThreatProtection name="JSON-Protection" enabled="true">
|
||||
<Source>request</Source>
|
||||
<ArrayElementCount>20</ArrayElementCount>
|
||||
<ContainerDepth>10</ContainerDepth>
|
||||
<ObjectEntryCount>15</ObjectEntryCount>
|
||||
<ObjectEntryNameLength>50</ObjectEntryNameLength>
|
||||
<StringValueLength>500</StringValueLength>
|
||||
</JSONThreatProtection>
|
||||
-->
|
||||
|
||||
<!-- XML Threat Protection -->
|
||||
<!--
|
||||
<XMLThreatProtection name="XML-Protection" enabled="true">
|
||||
<Source>request</Source>
|
||||
<StructureLimits>
|
||||
<NodeDepth>10</NodeDepth>
|
||||
<AttributeCountPerElement>5</AttributeCountPerElement>
|
||||
<NamespaceCountPerElement>3</NamespaceCountPerElement>
|
||||
<ChildCount includeComment="true" includeElement="true"
|
||||
includeProcessingInstruction="true" includeText="true">10</ChildCount>
|
||||
</StructureLimits>
|
||||
<ValueLimits>
|
||||
<Text>500</Text>
|
||||
<Attribute>100</Attribute>
|
||||
<NamespaceURI>256</NamespaceURI>
|
||||
<Comment>256</Comment>
|
||||
<ProcessingInstructionData>256</ProcessingInstructionData>
|
||||
</ValueLimits>
|
||||
</XMLThreatProtection>
|
||||
-->
|
||||
|
||||
<!-- Regular Expression Protection -->
|
||||
<!--
|
||||
<RegularExpressionProtection name="Regex-Protection" enabled="true">
|
||||
<Source>request</Source>
|
||||
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
|
||||
<URIPath>
|
||||
<Pattern>.*[;<>].*</Pattern>
|
||||
</URIPath>
|
||||
<QueryParam name="search">
|
||||
<Pattern>.*[;<>'\"].*</Pattern>
|
||||
</QueryParam>
|
||||
<Header name="User-Agent">
|
||||
<Pattern>.*sqlmap.*</Pattern>
|
||||
</Header>
|
||||
<JSONPayload>
|
||||
<JSONPath>$.user.input</JSONPath>
|
||||
<Pattern>.*<script.*</Pattern>
|
||||
</JSONPayload>
|
||||
</RegularExpressionProtection>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
FAULT HANDLING POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- Raise Fault -->
|
||||
<!--
|
||||
<RaiseFault name="Raise-Custom-Error" enabled="true">
|
||||
<FaultResponse>
|
||||
<Set>
|
||||
<StatusCode>400</StatusCode>
|
||||
<ReasonPhrase>Bad Request</ReasonPhrase>
|
||||
<Headers>
|
||||
<Header name="Content-Type">application/json</Header>
|
||||
</Headers>
|
||||
<Payload contentType="application/json">
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": "The request is invalid",
|
||||
"details": "{fault.cause}"
|
||||
}
|
||||
}
|
||||
</Payload>
|
||||
</Set>
|
||||
</FaultResponse>
|
||||
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
|
||||
</RaiseFault>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ========================================
|
||||
LOGGING POLICIES
|
||||
======================================== -->
|
||||
|
||||
<!-- Message Logging -->
|
||||
<!--
|
||||
<MessageLogging name="Log-Request" enabled="true">
|
||||
<Syslog>
|
||||
<Message>[{organization.name}] Request: {request.verb} {request.uri}</Message>
|
||||
<Host>syslog.example.com</Host>
|
||||
<Port>514</Port>
|
||||
<Protocol>TCP</Protocol>
|
||||
</Syslog>
|
||||
<logLevel>INFO</logLevel>
|
||||
</MessageLogging>
|
||||
-->
|
||||
|
||||
<!-- Statistics Collector -->
|
||||
<!--
|
||||
<StatisticsCollector name="Collect-Metrics" enabled="true">
|
||||
<Statistics>
|
||||
<Statistic name="apiName" ref="apiproxy.name" type="string"/>
|
||||
<Statistic name="responseTime" ref="response.time" type="integer"/>
|
||||
<Statistic name="statusCode" ref="response.status.code" type="integer"/>
|
||||
<Statistic name="clientIP" ref="client.ip" type="string"/>
|
||||
</Statistics>
|
||||
</StatisticsCollector>
|
||||
-->
|
||||
249
templates/groovy-script-template.groovy
Normal file
249
templates/groovy-script-template.groovy
Normal file
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* SAP Cloud Integration - Groovy Script Template
|
||||
*
|
||||
* Usage: Replace placeholders and customize for your use case
|
||||
*
|
||||
* Placeholders:
|
||||
* - {{SCRIPT_NAME}}: Name/description of script purpose
|
||||
* - {{AUTHOR}}: Script author
|
||||
* - {{DATE}}: Creation date
|
||||
*
|
||||
* Documentation:
|
||||
* - Scripting Guidelines: https://github.com/SAP-docs/sap-btp-integration-suite/blob/main/docs/ci/Development/general-scripting-guidelines-fcbf0f2.md
|
||||
* - Script API: https://github.com/SAP-docs/sap-btp-integration-suite/blob/main/docs/ci/Development/access-headers-and-properties-in-scripts-6bc5ed1.md
|
||||
*/
|
||||
|
||||
import com.sap.gateway.ip.core.customdev.util.Message
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
/**
|
||||
* {{SCRIPT_NAME}}
|
||||
*
|
||||
* @author {{AUTHOR}}
|
||||
* @date {{DATE}}
|
||||
*
|
||||
* Input:
|
||||
* - Body: Description of expected input format
|
||||
* - Headers: List of required headers
|
||||
* - Properties: List of required properties
|
||||
*
|
||||
* Output:
|
||||
* - Body: Description of output format
|
||||
* - Headers: List of headers set
|
||||
* - Properties: List of properties set
|
||||
*/
|
||||
def Message processData(Message message) {
|
||||
// Initialize logger
|
||||
def log = LoggerFactory.getLogger("script.{{SCRIPT_NAME}}")
|
||||
|
||||
try {
|
||||
// ===========================================
|
||||
// 1. GET MESSAGE COMPONENTS
|
||||
// ===========================================
|
||||
|
||||
// Get message body (use InputStream for large payloads)
|
||||
def body = message.getBody(String.class)
|
||||
// def bodyStream = message.getBody(java.io.InputStream.class)
|
||||
|
||||
// Get headers
|
||||
def contentType = message.getHeader("Content-Type", String.class)
|
||||
def customHeader = message.getHeader("X-Custom-Header", String.class)
|
||||
|
||||
// Get properties
|
||||
def property1 = message.getProperty("PropertyName")
|
||||
|
||||
// ===========================================
|
||||
// 2. PROCESS DATA
|
||||
// ===========================================
|
||||
|
||||
log.info("Processing started")
|
||||
|
||||
// Example: Parse JSON
|
||||
// def json = new groovy.json.JsonSlurper().parseText(body)
|
||||
// def value = json.fieldName
|
||||
|
||||
// Example: Parse XML (use parse() for streams, not parseText())
|
||||
// def xml = new groovy.xml.XmlSlurper().parse(message.getBody(java.io.InputStream.class))
|
||||
// def value = xml.element.text()
|
||||
|
||||
// Example: Process data
|
||||
def result = body.toUpperCase()
|
||||
|
||||
// ===========================================
|
||||
// 3. SET OUTPUT
|
||||
// ===========================================
|
||||
|
||||
// Set body
|
||||
message.setBody(result)
|
||||
|
||||
// Set headers
|
||||
message.setHeader("X-Processed", "true")
|
||||
message.setHeader("X-Timestamp", java.time.Instant.now().toString())
|
||||
|
||||
// Set properties
|
||||
message.setProperty("ProcessingStatus", "completed")
|
||||
|
||||
log.info("Processing completed successfully")
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Processing failed: ${e.message}", e)
|
||||
message.setProperty("ErrorMessage", e.message)
|
||||
// Use StringWriter for readable stack trace
|
||||
def sw = new StringWriter()
|
||||
e.printStackTrace(new PrintWriter(sw))
|
||||
message.setProperty("ErrorStackTrace", sw.toString())
|
||||
throw e // Re-throw to trigger exception handling
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
|
||||
// ===========================================
|
||||
// ADDITIONAL SCRIPT PATTERNS
|
||||
// ===========================================
|
||||
|
||||
/**
|
||||
* Pattern: JSON Transformation
|
||||
*/
|
||||
/*
|
||||
def Message transformJson(Message message) {
|
||||
def log = LoggerFactory.getLogger("script.transformJson")
|
||||
|
||||
def body = message.getBody(String.class)
|
||||
def input = new groovy.json.JsonSlurper().parseText(body)
|
||||
|
||||
// Transform (use explicit UTC timezone for ISO 8601 format)
|
||||
def output = [
|
||||
id: input.customerId,
|
||||
name: input.customerName,
|
||||
timestamp: new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"))
|
||||
]
|
||||
|
||||
message.setBody(groovy.json.JsonOutput.toJson(output))
|
||||
return message
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern: XML Transformation
|
||||
*/
|
||||
/*
|
||||
def Message transformXml(Message message) {
|
||||
def log = LoggerFactory.getLogger("script.transformXml")
|
||||
|
||||
// Use parse() with InputStream for better memory handling
|
||||
def bodyStream = message.getBody(java.io.InputStream.class)
|
||||
def xml = new groovy.xml.XmlSlurper().parse(bodyStream)
|
||||
|
||||
// Access elements
|
||||
def id = xml.customer.@id.text()
|
||||
def name = xml.customer.name.text()
|
||||
|
||||
// Build new XML
|
||||
def writer = new StringWriter()
|
||||
def builder = new groovy.xml.MarkupBuilder(writer)
|
||||
builder.response {
|
||||
customerId(id)
|
||||
customerName(name)
|
||||
processed(true)
|
||||
}
|
||||
|
||||
message.setBody(writer.toString())
|
||||
return message
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern: Secure Parameter Access
|
||||
*/
|
||||
/*
|
||||
def Message accessSecureParams(Message message) {
|
||||
import com.sap.it.api.ITApiFactory
|
||||
import com.sap.it.api.securestore.SecureStoreService
|
||||
|
||||
def secureStore = ITApiFactory.getService(SecureStoreService.class, null)
|
||||
def credential = secureStore.getUserCredential("CredentialName")
|
||||
|
||||
def username = credential.getUsername()
|
||||
def password = new String(credential.getPassword())
|
||||
|
||||
// Use credentials...
|
||||
return message
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern: Value Mapping Lookup
|
||||
*/
|
||||
/*
|
||||
def Message lookupValueMapping(Message message) {
|
||||
import com.sap.it.api.ITApiFactory
|
||||
import com.sap.it.api.mapping.ValueMappingApi
|
||||
|
||||
def vmApi = ITApiFactory.getService(ValueMappingApi.class, null)
|
||||
|
||||
def targetValue = vmApi.getMappedValue(
|
||||
"SourceAgency",
|
||||
"SourceIdentifier",
|
||||
"SourceValue",
|
||||
"TargetAgency",
|
||||
"TargetIdentifier"
|
||||
)
|
||||
|
||||
message.setProperty("MappedValue", targetValue)
|
||||
return message
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern: Dynamic Routing
|
||||
*/
|
||||
/*
|
||||
def Message dynamicRouting(Message message) {
|
||||
def body = message.getBody(String.class)
|
||||
def json = new groovy.json.JsonSlurper().parseText(body)
|
||||
|
||||
def endpoint
|
||||
switch(json.region?.toUpperCase()) {
|
||||
case "US":
|
||||
endpoint = "https://us-api.example.com/v1"
|
||||
break
|
||||
case "EU":
|
||||
endpoint = "https://eu-api.example.com/v1"
|
||||
break
|
||||
default:
|
||||
endpoint = "https://default-api.example.com/v1"
|
||||
}
|
||||
|
||||
message.setProperty("DynamicEndpoint", endpoint)
|
||||
return message
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern: Attachment Handling
|
||||
*/
|
||||
/*
|
||||
def Message handleAttachments(Message message) {
|
||||
import javax.activation.DataHandler
|
||||
|
||||
// Get all attachments
|
||||
def attachments = message.getAttachments()
|
||||
|
||||
attachments.each { name, dataHandler ->
|
||||
def content = dataHandler.getInputStream().text
|
||||
// Process attachment...
|
||||
}
|
||||
|
||||
// Add new attachment
|
||||
def newContent = "Attachment content"
|
||||
def dataSource = new javax.mail.util.ByteArrayDataSource(
|
||||
newContent.getBytes(),
|
||||
"text/plain"
|
||||
)
|
||||
message.addAttachmentObject("output.txt", new DataHandler(dataSource))
|
||||
|
||||
return message
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user