use of org.wso2.carbon.apimgt.tracing.TracingSpan in project carbon-apimgt by wso2.
the class APIManagerExtensionHandler method handleResponse.
@MethodStats
public boolean handleResponse(MessageContext messageContext) {
Timer.Context context = startMetricTimer(DIRECTION_OUT);
long executionStartTime = System.nanoTime();
TracingSpan responseMediationSpan = null;
if (Util.tracingEnabled()) {
TracingSpan responseLatencySpan = (TracingSpan) messageContext.getProperty(APIMgtGatewayConstants.RESOURCE_SPAN);
TracingTracer tracer = Util.getGlobalTracer();
responseMediationSpan = Util.startSpan(APIMgtGatewayConstants.RESPONSE_MEDIATION, responseLatencySpan, tracer);
}
try {
return mediate(messageContext, DIRECTION_OUT);
} catch (Exception e) {
if (Util.tracingEnabled() && responseMediationSpan != null) {
Util.setTag(responseMediationSpan, APIMgtGatewayConstants.ERROR, APIMgtGatewayConstants.RESPONSE_MEDIATION_ERROR);
}
throw e;
} finally {
if (Util.tracingEnabled()) {
Util.finishSpan(responseMediationSpan);
}
messageContext.setProperty(APIMgtGatewayConstants.RESPONSE_MEDIATION_LATENCY, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - executionStartTime));
stopMetricTimer(context);
}
}
use of org.wso2.carbon.apimgt.tracing.TracingSpan in project carbon-apimgt by wso2.
the class CORSRequestHandler method handleRequest.
@MethodStats
public boolean handleRequest(MessageContext messageContext) {
Timer.Context context = startMetricTimer();
TracingSpan CORSRequestHandlerSpan = null;
if (Util.tracingEnabled()) {
TracingSpan responseLatencySpan = (TracingSpan) messageContext.getProperty(APIMgtGatewayConstants.RESOURCE_SPAN);
TracingTracer tracer = Util.getGlobalTracer();
CORSRequestHandlerSpan = Util.startSpan(APIMgtGatewayConstants.CORS_REQUEST_HANDLER, responseLatencySpan, tracer);
}
if (Utils.isGraphQLSubscriptionRequest(messageContext)) {
if (log.isDebugEnabled()) {
log.debug("Skipping GraphQL subscription handshake request.");
}
return true;
}
try {
if (!initializeHeaderValues) {
initializeHeaders();
}
String apiContext = (String) messageContext.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) messageContext.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
String httpMethod = (String) ((Axis2MessageContext) messageContext).getAxis2MessageContext().getProperty(Constants.Configuration.HTTP_METHOD);
API selectedApi = Utils.getSelectedAPI(messageContext);
org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext) messageContext).getAxis2MessageContext();
Map headers = (Map) axis2MC.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
String corsRequestMethod = (String) headers.get(APIConstants.CORSHeaders.ACCESS_CONTROL_REQUEST_METHOD);
Resource selectedResource = null;
Utils.setSubRequestPath(selectedApi, messageContext);
if (selectedApi != null) {
Resource[] allAPIResources = selectedApi.getResources();
Set<Resource> acceptableResources = new LinkedHashSet<>();
for (Resource resource : allAPIResources) {
// If the requesting method is OPTIONS or if the Resource contains the requesting method
if ((RESTConstants.METHOD_OPTIONS.equals(httpMethod) && resource.getMethods() != null && Arrays.asList(resource.getMethods()).contains(corsRequestMethod)) || (resource.getMethods() != null && Arrays.asList(resource.getMethods()).contains(httpMethod))) {
acceptableResources.add(resource);
}
}
if (!acceptableResources.isEmpty()) {
for (RESTDispatcher dispatcher : RESTUtils.getDispatchers()) {
Resource resource = dispatcher.findResource(messageContext, acceptableResources);
if (resource != null) {
selectedResource = resource;
break;
}
}
if (selectedResource == null) {
handleResourceNotFound(messageContext, Arrays.asList(allAPIResources));
return false;
}
} else // If no acceptable resources are found
{
// We're going to send a 405 or a 404. Run the following logic to determine which.
handleResourceNotFound(messageContext, Arrays.asList(allAPIResources));
return false;
}
// No matching resource found
if (selectedResource == null) {
// Respond with a 404
onResourceNotFoundError(messageContext, HttpStatus.SC_NOT_FOUND, APIMgtGatewayConstants.RESOURCE_NOT_FOUND_ERROR_MSG);
return false;
}
}
String resourceString = selectedResource.getDispatcherHelper().getString();
String resourceCacheKey = APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, resourceString, httpMethod);
messageContext.setProperty(APIConstants.API_ELECTED_RESOURCE, resourceString);
messageContext.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey);
messageContext.setProperty(APIConstants.REST_METHOD, httpMethod);
// If this is an OPTIONS request
if (APIConstants.SupportedHTTPVerbs.OPTIONS.name().equalsIgnoreCase(httpMethod)) {
// If the OPTIONS method is explicity specified in the resource
if (Arrays.asList(selectedResource.getMethods()).contains(APIConstants.SupportedHTTPVerbs.OPTIONS.name())) {
// We will not handle the CORS headers, let the back-end do it.
return true;
}
setCORSHeaders(messageContext, selectedResource);
Mediator corsSequence = messageContext.getSequence(APIConstants.CORS_SEQUENCE_NAME);
if (corsSequence != null) {
corsSequence.mediate(messageContext);
}
Utils.send(messageContext, HttpStatus.SC_OK);
return false;
} else if (APIConstants.IMPLEMENTATION_TYPE_INLINE.equalsIgnoreCase(apiImplementationType)) {
setCORSHeaders(messageContext, selectedResource);
messageContext.getSequence(APIConstants.CORS_SEQUENCE_NAME).mediate(messageContext);
}
setCORSHeaders(messageContext, selectedResource);
return true;
} catch (Exception e) {
if (Util.tracingEnabled() && CORSRequestHandlerSpan != null) {
Util.setTag(CORSRequestHandlerSpan, APIMgtGatewayConstants.ERROR, APIMgtGatewayConstants.CORS_REQUEST_HANDLER_ERROR);
}
throw e;
} finally {
stopMetricTimer(context);
if (Util.tracingEnabled()) {
Util.finishSpan(CORSRequestHandlerSpan);
}
}
}
use of org.wso2.carbon.apimgt.tracing.TracingSpan in project carbon-apimgt by wso2.
the class APIMgtLatencySynapseHandler method handleResponseOutFlow.
@Override
public boolean handleResponseOutFlow(MessageContext messageContext) {
if (Util.tracingEnabled()) {
Object resourceSpanObject = messageContext.getProperty(APIMgtGatewayConstants.RESOURCE_SPAN);
if (resourceSpanObject != null) {
GatewayUtils.setAPIResource((TracingSpan) resourceSpanObject, messageContext);
Util.finishSpan((TracingSpan) resourceSpanObject);
}
TracingSpan responseLatencySpan = (TracingSpan) messageContext.getProperty(APIMgtGatewayConstants.RESPONSE_LATENCY);
GatewayUtils.setAPIRelatedTags(responseLatencySpan, messageContext);
API api = GatewayUtils.getAPI(messageContext);
if (api != null) {
Util.updateOperation(responseLatencySpan, api.getApiName().concat("--").concat(api.getApiVersion()).concat("--").concat(GatewayUtils.getTenantDomain()));
}
Util.finishSpan(responseLatencySpan);
}
return true;
}
use of org.wso2.carbon.apimgt.tracing.TracingSpan in project carbon-apimgt by wso2.
the class APIKeyValidationService method validateKey.
/**
* Validates the access tokens issued for a particular user to access an API.
*
* @param context Requested context
* @param accessToken Provided access token
* @return APIKeyValidationInfoDTO with authorization info and tier info if authorized. If it is not
* authorized, tier information will be <pre>null</pre>
* @throws APIKeyMgtException Error occurred when accessing the underlying database or registry.
*/
public APIKeyValidationInfoDTO validateKey(String context, String version, String accessToken, String requiredAuthenticationLevel, String matchingResource, String httpVerb, String tenantDomain, List keyManagers) throws APIKeyMgtException, APIManagementException {
TracingSpan validateMainSpan = null;
TracingSpan getAccessTokenCacheSpan = null;
TracingSpan fetchingKeyValDTOSpan = null;
TracingSpan validateTokenSpan = null;
TracingSpan validateSubscriptionSpan = null;
TracingSpan validateScopeSpan = null;
TracingSpan generateJWTSpan = null;
TracingSpan keyCache = null;
TracingSpan keyValResponseSpan = null;
TracingTracer tracer = Util.getGlobalTracer();
Timer timer = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_MAIN"));
Timer.Context timerContext = timer.start();
MessageContext axis2MessageContext = MessageContext.getCurrentMessageContext();
if (Util.tracingEnabled() && axis2MessageContext != null) {
Map map = (Map) axis2MessageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
TracingSpan spanContext = Util.extract(tracer, map);
validateMainSpan = Util.startSpan(TracingConstants.VALIDATE_MAIN, spanContext, tracer);
}
Map headersMap = null;
String activityID = null;
try {
if (axis2MessageContext != null) {
MessageContext responseMessageContext = axis2MessageContext.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
if (responseMessageContext != null) {
if (log.isDebugEnabled()) {
List headersList = new ArrayList();
Object headers = axis2MessageContext.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
if (headers != null && headers instanceof Map) {
headersMap = (Map) headers;
activityID = (String) headersMap.get("activityID");
}
if (headersMap != null) {
headersList.add(new Header("activityID", (String) headersMap.get("activityID")));
}
responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headersList);
}
}
}
} catch (AxisFault axisFault) {
throw new APIKeyMgtException("Error while building response messageContext: " + axisFault.getLocalizedMessage());
}
if (log.isDebugEnabled()) {
String logMsg = "KeyValidation request from gateway: requestTime= " + new SimpleDateFormat("[yyyy.MM.dd HH:mm:ss,SSS zzz]").format(new Date()) + " , for:" + context + " with accessToken=" + accessToken;
if (activityID != null) {
logMsg = logMsg + " , transactionId=" + activityID;
}
log.debug(logMsg);
}
TokenValidationContext validationContext = new TokenValidationContext();
validationContext.setAccessToken(accessToken);
validationContext.setContext(context);
validationContext.setHttpVerb(httpVerb);
validationContext.setMatchingResource(matchingResource);
validationContext.setRequiredAuthenticationLevel(requiredAuthenticationLevel);
validationContext.setValidationInfoDTO(new APIKeyValidationInfoDTO());
validationContext.setVersion(version);
validationContext.setTenantDomain(tenantDomain);
validationContext.setKeyManagers(keyManagers);
if (Util.tracingEnabled()) {
getAccessTokenCacheSpan = Util.startSpan(TracingConstants.GET_ACCESS_TOKEN_CACHE_KEY, validateMainSpan, tracer);
}
String cacheKey = APIUtil.getAccessTokenCacheKey(accessToken, context, version, matchingResource, httpVerb, requiredAuthenticationLevel);
validationContext.setCacheKey(cacheKey);
if (Util.tracingEnabled()) {
Util.finishSpan(getAccessTokenCacheSpan);
fetchingKeyValDTOSpan = Util.startSpan(TracingConstants.FETCHING_API_KEY_VAL_INFO_DTO_FROM_CACHE, validateMainSpan, tracer);
}
APIKeyValidationInfoDTO infoDTO = APIKeyMgtUtil.getFromKeyManagerCache(cacheKey);
if (Util.tracingEnabled()) {
Util.finishSpan(fetchingKeyValDTOSpan);
}
if (infoDTO != null) {
validationContext.setCacheHit(true);
log.debug("APIKeyValidationInfoDTO fetched from cache. Setting cache hit to true...");
validationContext.setValidationInfoDTO(infoDTO);
}
log.debug("Before calling Validate Token method...");
Timer timer2 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_TOKEN"));
Timer.Context timerContext2 = timer2.start();
if (Util.tracingEnabled()) {
validateTokenSpan = Util.startSpan(TracingConstants.VALIDATE_TOKEN, validateMainSpan, tracer);
}
KeyValidationHandler keyValidationHandler = ServiceReferenceHolder.getInstance().getKeyValidationHandler(tenantDomain);
boolean state = keyValidationHandler.validateToken(validationContext);
timerContext2.stop();
if (Util.tracingEnabled()) {
Util.finishSpan(validateTokenSpan);
}
log.debug("State after calling validateToken ... " + state);
if (state) {
Timer timer3 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_SUBSCRIPTION"));
Timer.Context timerContext3 = timer3.start();
if (Util.tracingEnabled()) {
validateSubscriptionSpan = Util.startSpan(TracingConstants.VALIDATE_SUBSCRIPTION, validateMainSpan, tracer);
}
state = keyValidationHandler.validateSubscription(validationContext);
timerContext3.stop();
if (Util.tracingEnabled()) {
Util.finishSpan(validateSubscriptionSpan);
}
}
log.debug("State after calling validateSubscription... " + state);
if (state) {
Timer timer4 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "VALIDATE_SCOPES"));
Timer.Context timerContext4 = timer4.start();
if (Util.tracingEnabled()) {
validateScopeSpan = Util.startSpan(TracingConstants.VALIDATE_SCOPES, validateMainSpan, tracer);
}
state = keyValidationHandler.validateScopes(validationContext);
timerContext4.stop();
if (Util.tracingEnabled()) {
Util.finishSpan(validateScopeSpan);
}
}
log.debug("State after calling validateScopes... " + state);
if (state && APIKeyMgtDataHolder.isJwtGenerationEnabled() && validationContext.getValidationInfoDTO().getEndUserName() != null && !validationContext.isCacheHit()) {
Timer timer5 = MetricManager.timer(org.wso2.carbon.metrics.manager.Level.INFO, MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), "GENERATE_JWT"));
Timer.Context timerContext5 = timer5.start();
if (Util.tracingEnabled()) {
generateJWTSpan = Util.startSpan(TracingConstants.GENERATE_JWT, validateMainSpan, tracer);
}
keyValidationHandler.generateConsumerToken(validationContext);
timerContext5.stop();
if (Util.tracingEnabled()) {
Util.finishSpan(generateJWTSpan);
}
}
log.debug("State after calling generateConsumerToken... " + state);
if (!validationContext.isCacheHit()) {
if (Util.tracingEnabled()) {
keyCache = Util.startSpan(TracingConstants.WRITE_TO_KEY_MANAGER_CACHE, validateMainSpan, tracer);
}
APIKeyMgtUtil.writeToKeyManagerCache(cacheKey, validationContext.getValidationInfoDTO());
if (Util.tracingEnabled()) {
Util.finishSpan(keyCache);
}
}
if (Util.tracingEnabled()) {
keyValResponseSpan = Util.startSpan(TracingConstants.PUBLISHING_KEY_VALIDATION_RESPONSE, validateMainSpan, tracer);
}
if (log.isDebugEnabled() && axis2MessageContext != null) {
logMessageDetails(axis2MessageContext, validationContext.getValidationInfoDTO());
}
if (log.isDebugEnabled()) {
log.debug("APIKeyValidationInfoDTO before returning : " + validationContext.getValidationInfoDTO());
log.debug("KeyValidation response from keymanager to gateway for access token:" + accessToken + " at " + new SimpleDateFormat("[yyyy.MM.dd HH:mm:ss,SSS zzz]").format(new Date()));
}
if (Util.tracingEnabled()) {
Util.finishSpan(keyValResponseSpan);
}
timerContext.stop();
if (Util.tracingEnabled() && validateMainSpan != null) {
Util.finishSpan(validateMainSpan);
}
return validationContext.getValidationInfoDTO();
}
Aggregations