如何让Camel FTP在CronScheduledRoutePolicy触发路由后仅轮询一次文件
Hey there! Let's get your Camel FTP → SharePoint monthly report workflow sorted out—you've already got a great foundation with the filename filter and cron schedule, so let's tie it all together properly.
1. Validate Your Existing FTP & Scheduling Config
First, let's formalize the setup you've started, filling in logical gaps for clarity:
<!-- Filename filter for ACE reports in CSREPORT folder --> <bean id="aceReportFileNameFilter" class="org.apache.camel.component.file.GenericFileFilter"> <method name="accept"> <argument type="org.apache.camel.component.file.GenericFile"> <simple>${file:name} regex 'ACE_Report_.*\.pdf'</simple> </argument> </method> </bean> <!-- Matching filter for your second report (e.g., BCD Report) --> <bean id="bcdReportFileNameFilter" class="org.apache.camel.component.file.GenericFileFilter"> <method name="accept"> <argument type="org.apache.camel.component.file.GenericFile"> <simple>${file:name} regex 'BCD_Report_.*\.xlsx'</simple> </argument> </method> </bean> <!-- Cron Schedule: Trigger twice monthly (example: 1st and 15th at 2 AM) --> <bean id="monthlyTriggerPolicy" class="org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy"> <property name="routeStartCron" value="0 0 2 1,15 * ?"/> <!-- Adjust to your desired time/dates --> <property name="routeStartRepeatCount" value="-1"/> <!-- Repeat indefinitely --> </bean> <!-- Base Camel Context with FTP Routes --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- Route for ACE Report --> <route id="ftp-download-ace-report" routePolicyRef="monthlyTriggerPolicy"> <from uri="ftp://your-ftp-username@ftp.your-domain.com/CSREPORT?password=your-ftp-password&filter=#aceReportFileNameFilter&delete=false"/> <!-- SharePoint upload step will go here --> </route> <!-- Route for Second Report --> <route id="ftp-download-second-report" routePolicyRef="monthlyTriggerPolicy"> <from uri="ftp://your-ftp-username@ftp.your-domain.com/CSREPORT?password=your-ftp-password&filter=#bcdReportFileNameFilter&delete=false"/> <!-- SharePoint upload step will go here --> </route> </camelContext>
Quick notes: Tweak the cron expression to match your exact trigger times (use a cron tester if needed), and set delete=true only if you want to remove files from FTP post-download.
2. Add SharePoint Upload Logic
Next, integrate Camel's SharePoint component to push downloaded files to your site. We'll use SharePoint Online for this example:
Step 1: Add Dependency (Maven)
Add this to your pom.xml to pull in the SharePoint component (match your Camel version):
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-sharepoint-online</artifactId> <version>4.3.0</version> <!-- Use your Camel version --> </dependency>
Step 2: Configure SharePoint Authentication
Add a bean for secure SharePoint access (store credentials in environment variables/properties for production!):
<bean id="sharepointAuth" class="org.apache.camel.component.sharepoint.online.auth.SharePointOnlineAuthentication"> <property name="clientId" value="your-sharepoint-client-id"/> <property name="clientSecret" value="your-sharepoint-client-secret"/> <property name="tenantId" value="your-azure-tenant-id"/> <property name="siteUrl" value="https://your-tenant.sharepoint.com/sites/YourReportSite"/> </bean>
Step 3: Update Routes to Include Upload
Modify your FTP routes to add the SharePoint upload step:
<route id="ftp-download-ace-report" routePolicyRef="monthlyTriggerPolicy"> <from uri="ftp://your-ftp-username@ftp.your-domain.com/CSREPORT?password=your-ftp-password&filter=#aceReportFileNameFilter&delete=false"/> <!-- Upload to target SharePoint document library --> <to uri="sharepoint-online://sites/YourReportSite/Shared%20Documents/MonthlyReports?authentication=#sharepointAuth&operation=create"/> <log message="Successfully uploaded ACE Report to SharePoint: ${file:name}"/> </route>
Replace Shared%20Documents/MonthlyReports with your actual document library path (URL-encode spaces!).
3. Critical Reliability Tips
- Error Handling: Add a retry/alert block to handle FTP/SharePoint failures:
<onException> <exception>java.io.IOException</exception> <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="30000"/> <!-- Retry 3x every 30s --> <log message="Failed to process file ${file:name}: ${exception.message}"/> <to uri="file://./local-error-folder"/> <!-- Store failed files locally --> </onException> - Idempotency: Avoid re-downloading the same file by adding an idempotent repository:
<from uri="ftp://...&idempotent=true&idempotentRepository=#fileIdempotentRepo"/> <bean id="fileIdempotentRepo" class="org.apache.camel.processor.idempotent.FileIdempotentRepository"> <property name="fileStore" value="./idempotent-store"/> </bean> - Test First: Use a temporary cron (e.g.,
0 */5 * * * ?to run every 5 minutes) to test the full workflow before relying on the monthly trigger.
4. Troubleshooting Common Hiccups
- FTP Timeouts: Add
passiveMode=trueto your FTP URI if your server requires passive mode. - SharePoint Permissions: Ensure your client ID/secret has
Site.ReadWrite.Allor specific library permissions in Azure AD. - Filter Mismatches: Double-check your regex in the filename filter—case sensitivity matters!
内容的提问来源于stack exchange,提问作者RKA

