use of org.wso2.carbon.identity.application.authentication.framework.AsyncReturn in project identity-conditional-auth-functions by wso2-extensions.
the class AbstractHTTPFunction method executeHttpMethod.
protected void executeHttpMethod(HttpUriRequest request, Map<String, Object> eventHandlers) {
AsyncProcess asyncProcess = new AsyncProcess((context, asyncReturn) -> {
JSONObject json = null;
int responseCode;
String outcome;
String epUrl = null;
if (request.getURI() != null) {
epUrl = request.getURI().toString();
}
if (!isValidRequestDomain(request.getURI())) {
outcome = Constants.OUTCOME_FAIL;
LOG.error("Provided Url does not contain a allowed domain. Invalid Url: " + epUrl);
asyncReturn.accept(context, Collections.emptyMap(), outcome);
return;
}
try (CloseableHttpResponse response = client.execute(request)) {
responseCode = response.getStatusLine().getStatusCode();
if (responseCode >= 200 && responseCode < 300) {
outcome = Constants.OUTCOME_SUCCESS;
String jsonString = EntityUtils.toString(response.getEntity());
JSONParser parser = new JSONParser();
json = (JSONObject) parser.parse(jsonString);
} else {
outcome = Constants.OUTCOME_FAIL;
}
} catch (IllegalArgumentException e) {
LOG.error("Invalid Url: " + epUrl, e);
outcome = Constants.OUTCOME_FAIL;
} catch (ConnectTimeoutException e) {
LOG.error("Error while waiting to connect to " + epUrl, e);
outcome = Constants.OUTCOME_TIMEOUT;
} catch (SocketTimeoutException e) {
LOG.error("Error while waiting for data from " + epUrl, e);
outcome = Constants.OUTCOME_TIMEOUT;
} catch (IOException e) {
LOG.error("Error while calling endpoint. ", e);
outcome = Constants.OUTCOME_FAIL;
} catch (ParseException e) {
LOG.error("Error while parsing response. ", e);
outcome = Constants.OUTCOME_FAIL;
}
asyncReturn.accept(context, json != null ? json : Collections.emptyMap(), outcome);
});
JsGraphBuilder.addLongWaitProcess(asyncProcess, eventHandlers);
}
use of org.wso2.carbon.identity.application.authentication.framework.AsyncReturn in project carbon-identity-framework by wso2.
the class AsyncSequenceExecutor method exec.
public void exec(AsyncCaller caller, AsyncReturn returnFunction, AuthenticationContext authenticationContext) throws FrameworkException {
if (returnFunction == null) {
throw new FrameworkException("Can not execute the async process, as no callback function registered on " + "returnFunction.");
}
AsyncReturn wrappedReturn = (ctx, m, r) -> {
this.execReturn(returnFunction, ctx, m, r);
};
executorService.submit(new AsyncCallerTask(new ObservingAsyncProcess(caller, wrappedReturn, authenticationContext)));
}
use of org.wso2.carbon.identity.application.authentication.framework.AsyncReturn in project carbon-identity-framework by wso2.
the class GraphBasedSequenceHandler method callExternalSystem.
private boolean callExternalSystem(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context, SequenceConfig sequenceConfig, LongWaitNode longWaitNode) throws FrameworkException {
AsyncProcess asyncProcess = longWaitNode.getAsyncProcess();
if (asyncProcess == null) {
return false;
}
AsyncCaller caller = asyncProcess.getAsyncCaller();
AsyncReturn asyncReturn = rethrowTriConsumer((authenticationContext, data, result) -> {
authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_CALL_AND_WAIT_STATUS, result);
authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_CALL_AND_WAIT_DATA, data);
if (!promptOnLongWait()) {
synchronized (context) {
context.notify();
}
}
});
if (caller != null) {
FrameworkServiceDataHolder.getInstance().getAsyncSequenceExecutor().exec(caller, asyncReturn, context);
if (!promptOnLongWait()) {
int waitTimeout = getLongWaitTimeout();
synchronized (context) {
try {
context.wait(waitTimeout);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Thread interrupted while waiting for the external call to complete for session " + "data key: " + context.getContextIdentifier() + ". ", e);
}
}
resumeLongWait(request, response, context);
}
return true;
}
return false;
}
use of org.wso2.carbon.identity.application.authentication.framework.AsyncReturn in project identity-conditional-auth-functions by wso2-extensions.
the class CallChoreoFunctionImpl method callChoreo.
@Override
public void callChoreo(Map<String, String> connectionMetaData, Map<String, Object> payloadData, Map<String, Object> eventHandlers) {
AsyncProcess asyncProcess = new AsyncProcess((authenticationContext, asyncReturn) -> {
String epUrl = connectionMetaData.get(URL_VARIABLE_NAME);
try {
if (!isValidChoreoDomain(epUrl)) {
LOG.error("Provided Url does not contain a configured choreo domain. Invalid Url: " + epUrl);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), Constants.OUTCOME_FAIL);
return;
}
String tenantDomain = authenticationContext.getTenantDomain();
HttpPost request = new HttpPost(epUrl);
request.setHeader(ACCEPT, TYPE_APPLICATION_JSON);
request.setHeader(CONTENT_TYPE, TYPE_APPLICATION_JSON);
String apiKey;
if (StringUtils.isNotEmpty(connectionMetaData.get(API_KEY_VARIABLE_NAME))) {
apiKey = connectionMetaData.get(API_KEY_VARIABLE_NAME);
} else {
String apiKeyAlias = connectionMetaData.get(API_KEY_ALIAS_VARIABLE_NAME);
apiKey = getResolvedSecret(apiKeyAlias);
}
request.setHeader(API_KEY, apiKey);
JSONObject jsonObject = new JSONObject();
for (Map.Entry<String, Object> dataElements : payloadData.entrySet()) {
jsonObject.put(dataElements.getKey(), dataElements.getValue());
}
request.setEntity(new StringEntity(jsonObject.toJSONString()));
CloseableHttpAsyncClient client = ChoreoFunctionServiceHolder.getInstance().getClientManager().getClient(tenantDomain);
client.execute(request, new FutureCallback<HttpResponse>() {
@Override
public void completed(final HttpResponse response) {
String outcome;
JSONObject json = null;
int responseCode = response.getStatusLine().getStatusCode();
try {
if (responseCode == 200) {
try {
String jsonString = EntityUtils.toString(response.getEntity());
JSONParser parser = new JSONParser();
json = (JSONObject) parser.parse(jsonString);
outcome = Constants.OUTCOME_SUCCESS;
} catch (ParseException e) {
LOG.error("Error while building response from Choreo call for " + "session data key: " + authenticationContext.getContextIdentifier(), e);
outcome = Constants.OUTCOME_FAIL;
} catch (IOException e) {
LOG.error("Error while reading response from Choreo call for " + "session data key: " + authenticationContext.getContextIdentifier(), e);
outcome = Constants.OUTCOME_FAIL;
}
} else {
outcome = Constants.OUTCOME_FAIL;
}
asyncReturn.accept(authenticationContext, json != null ? json : Collections.emptyMap(), outcome);
} catch (FrameworkException e) {
LOG.error("Error while proceeding after successful response from Choreo call for " + "session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
@Override
public void failed(final Exception ex) {
LOG.error("Failed to invoke Choreo for session data key: " + authenticationContext.getContextIdentifier(), ex);
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Calls to Choreo failed for session " + "data key: " + authenticationContext.getContextIdentifier());
}
String outcome = OUTCOME_FAIL;
if ((ex instanceof SocketTimeoutException) || (ex instanceof ConnectTimeoutException)) {
outcome = OUTCOME_TIMEOUT;
}
asyncReturn.accept(authenticationContext, Collections.emptyMap(), outcome);
} catch (FrameworkException e) {
LOG.error("Error while proceeding after failed response from Choreo " + "call for session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
@Override
public void cancelled() {
LOG.error("Invocation Choreo for session data key: " + authenticationContext.getContextIdentifier() + " is cancelled.");
try {
if (LOG.isDebugEnabled()) {
LOG.debug(" Calls to Choreo for session data key: " + authenticationContext.getContextIdentifier());
}
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (FrameworkException e) {
LOG.error("Error while proceeding after cancelled response from Choreo " + "call for session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
});
} catch (IllegalArgumentException e) {
LOG.error("Invalid endpoint Url: " + epUrl, e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (IOException e) {
LOG.error("Error while calling endpoint.", e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (SecretManagementException e) {
LOG.error("Error while resolving API key. ", e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
}
});
JsGraphBuilder.addLongWaitProcess(asyncProcess, eventHandlers);
}
use of org.wso2.carbon.identity.application.authentication.framework.AsyncReturn in project identity-conditional-auth-functions by wso2-extensions.
the class CallAnalyticsFunctionImpl method callAnalytics.
@Override
public void callAnalytics(Map<String, String> metadata, Map<String, Object> payloadData, Map<String, Object> eventHandlers) {
AsyncProcess asyncProcess = new AsyncProcess((authenticationContext, asyncReturn) -> {
String appName = metadata.get(PARAM_APP_NAME);
String inputStream = metadata.get(PARAM_INPUT_STREAM);
String receiverUrl = metadata.get(PARAM_EP_URL);
String targetPath;
try {
if (appName != null && inputStream != null) {
targetPath = "/" + appName + "/" + inputStream;
} else if (receiverUrl != null) {
targetPath = receiverUrl;
} else {
throw new FrameworkException("Target path cannot be found.");
}
String tenantDomain = authenticationContext.getTenantDomain();
String targetHostUrl = CommonUtils.getConnectorConfig(AnalyticsEngineConfigImpl.RECEIVER, tenantDomain);
if (targetHostUrl == null) {
throw new FrameworkException("Target host cannot be found.");
}
HttpPost request = new HttpPost(targetPath);
request.setHeader(ACCEPT, TYPE_APPLICATION_JSON);
request.setHeader(CONTENT_TYPE, TYPE_APPLICATION_JSON);
handleAuthentication(request, tenantDomain);
JSONObject jsonObject = new JSONObject();
JSONObject event = new JSONObject();
for (Map.Entry<String, Object> dataElements : payloadData.entrySet()) {
event.put(dataElements.getKey(), dataElements.getValue());
}
jsonObject.put("event", event);
request.setEntity(new StringEntity(jsonObject.toJSONString()));
String[] targetHostUrls = targetHostUrl.split(";");
HttpHost[] targetHosts = new HttpHost[targetHostUrls.length];
for (int i = 0; i < targetHostUrls.length; i++) {
URL hostUrl = new URL(targetHostUrls[i]);
targetHosts[i] = new HttpHost(hostUrl.getHost(), hostUrl.getPort(), hostUrl.getProtocol());
}
CloseableHttpAsyncClient client = ClientManager.getInstance().getClient(tenantDomain);
AtomicInteger requestAtomicInteger = new AtomicInteger(targetHosts.length);
for (final HttpHost targetHost : targetHosts) {
client.execute(targetHost, request, new FutureCallback<HttpResponse>() {
@Override
public void completed(final HttpResponse response) {
int responseCode = response.getStatusLine().getStatusCode();
try {
if (responseCode == 200) {
try {
String jsonString = EntityUtils.toString(response.getEntity());
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(jsonString);
asyncReturn.accept(authenticationContext, json, OUTCOME_SUCCESS);
} catch (ParseException e) {
LOG.error("Error while building response from analytics engine call for " + "session data key: " + authenticationContext.getContextIdentifier(), e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (IOException e) {
LOG.error("Error while reading response from analytics engine call for " + "session data key: " + authenticationContext.getContextIdentifier(), e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
}
} else {
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
}
} catch (FrameworkException e) {
LOG.error("Error while proceeding after successful response from analytics engine " + "call for session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
@Override
public void failed(final Exception ex) {
LOG.error("Failed to invoke analytics engine for session data key: " + authenticationContext.getContextIdentifier(), ex);
if (requestAtomicInteger.decrementAndGet() <= 0) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug(" All the calls to analytics engine failed for session " + "data key: " + authenticationContext.getContextIdentifier());
}
String outcome = OUTCOME_FAIL;
if ((ex instanceof SocketTimeoutException) || (ex instanceof ConnectTimeoutException)) {
outcome = OUTCOME_TIMEOUT;
}
asyncReturn.accept(authenticationContext, Collections.emptyMap(), outcome);
} catch (FrameworkException e) {
LOG.error("Error while proceeding after failed response from analytics engine " + "call for session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
}
@Override
public void cancelled() {
LOG.error("Invocation analytics engine for session data key: " + authenticationContext.getContextIdentifier() + " is cancelled.");
if (requestAtomicInteger.decrementAndGet() <= 0) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug(" All the calls to analytics engine failed for session " + "data key: " + authenticationContext.getContextIdentifier());
}
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (FrameworkException e) {
LOG.error("Error while proceeding after cancelled response from analytics engine " + "call for session data key: " + authenticationContext.getContextIdentifier(), e);
}
}
}
});
}
} catch (IOException e) {
LOG.error("Error while calling analytics engine. ", e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
} catch (IdentityEventException e) {
LOG.error("Error while creating authentication. ", e);
asyncReturn.accept(authenticationContext, Collections.emptyMap(), OUTCOME_FAIL);
}
});
JsGraphBuilder.addLongWaitProcess(asyncProcess, eventHandlers);
}
Aggregations