I have a scheduled batch class that updates my order payments however I am receiving an error that the callout is not supported. I have read other posts that for batch classes if Database.AllowCallouts is included it would be able to hit my other class methods to retrieve a token. However it is not working, this line is where the error is coming from:
global final String authToken = orderService.getAccessToken();
Here is my global class for mass order payments:
global class MassOrderPayments implements Database.Batchable<sObject>, Database.AllowsCallouts{
Map<Id, String> errorMap = new Map<Id,String>();
global final String authToken = orderService.getAccessToken();
global Database.QueryLocator start(Database.BatchableContext BC) {
if(authToken == null || authToken == ''){
throw new EDFException('Error sending scheduled payments, could not authenticate');
}
return Database.getQueryLocator('SELECT ID FROM Order WHERE Scheduled_Payment__c = TRUE');
}
global void execute(Database.BatchableContext BC, List<Order> orders) {
for(Order order : orders){
String result = orderService.processRESTPayments(check.id,true,authToken);
if(result != 'success'){
errorMap.put(check.id, result);
}
check.Scheduled__Payment__c = false;
}
update orders;
}
global void finish(Database.BatchableContext BC){
for(Id id : errorMap.keySet()){
EmailService.sendGenericEmail('Error Mass payingOrders', 'Order Id:' + id + ' Error Message:'+errorMap.get(id));
}
}
}
Here is my OrderService.getAccessToken() method:
public static String getAccessToken(){
try {
if(Test.isRunningTest()) {
return '12345678';
} else {
Http http = new Http();
HttpResponse response;
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndPoint(System.Label.TokenEndpoint);
req.setHeader('Accept', 'application/json');
req.setHeader('Accept-Language', 'en_US');
Blob headerValue = Blob.valueOf(System.Label.ClientID + ':' + System.Label.Secret);
String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
req.setBody('grant_type=client_credentials');
response = http.send(req);
if(response != null && response.getBody() != null){
TokenResponse jsonResponse = (TokenResponse) JSON.deserialize(response.getBody(), TokenResponse.class);
return jsonResponse.access_token;
}
}
}
catch(Exception e){
throw new EDFException(‘Error retrieving token'+e.getMessage()+''+e.getStackTraceString());
}
return null;
}
How would I proceed in grabbing my token?
The error I received:
Scheduled job 'ScheduleOrderPayments' threw unhandled exception.
caused by: EDFException: Error retreivingl auth tokenCallout from scheduled Apex not supported.
Class.orderService.getAccessToken: line 248, column 1
Class.MassOrderPayments.: line 4, column 1
Class.ScheduleOrderPayments.execute: line 3, column 1
Class.orderService.getAccessToken: line 256, column 1
Class.MassOrderPayments.: line 4, column 1
Class.ScheduleOrderPayments.execute: line 3, column 1
Schedule Class:
global class ScheduleMassOrderPayments implements Schedulable {
global void execute(SchedulableContext sc) {
MassOrderPayments orders = new MassOrderPayments();
Database.executeBatch(orders);
}
}
Test.isRunningTest()
where you should instead use mocks. It won't fix your issue to resolve, but you should avoid this pattern at all costs.orderService.getAccessToken()
inside yourstart
method. You'll have to make it non-final.