Search in sources :

Example 11 with TracingSpan

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);
    }
}
Also used : Timer(org.wso2.carbon.metrics.manager.Timer) TracingTracer(org.wso2.carbon.apimgt.tracing.TracingTracer) TracingSpan(org.wso2.carbon.apimgt.tracing.TracingSpan) MethodStats(org.wso2.carbon.apimgt.gateway.MethodStats)

Example 12 with TracingSpan

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);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TracingTracer(org.wso2.carbon.apimgt.tracing.TracingTracer) Resource(org.apache.synapse.api.Resource) RESTDispatcher(org.apache.synapse.api.dispatch.RESTDispatcher) Timer(org.wso2.carbon.metrics.manager.Timer) API(org.apache.synapse.api.API) Mediator(org.apache.synapse.Mediator) TracingSpan(org.wso2.carbon.apimgt.tracing.TracingSpan) Map(java.util.Map) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) MethodStats(org.wso2.carbon.apimgt.gateway.MethodStats)

Example 13 with TracingSpan

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;
}
Also used : API(org.wso2.carbon.apimgt.keymgt.model.entity.API) TracingSpan(org.wso2.carbon.apimgt.tracing.TracingSpan)

Example 14 with TracingSpan

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();
}
Also used : AxisFault(org.apache.axis2.AxisFault) TracingTracer(org.wso2.carbon.apimgt.tracing.TracingTracer) ArrayList(java.util.ArrayList) Date(java.util.Date) APIKeyMgtException(org.wso2.carbon.apimgt.keymgt.APIKeyMgtException) Timer(org.wso2.carbon.metrics.manager.Timer) Header(org.apache.commons.httpclient.Header) KeyValidationHandler(org.wso2.carbon.apimgt.keymgt.handlers.KeyValidationHandler) ArrayList(java.util.ArrayList) List(java.util.List) TracingSpan(org.wso2.carbon.apimgt.tracing.TracingSpan) MessageContext(org.apache.axis2.context.MessageContext) HashMap(java.util.HashMap) Map(java.util.Map) SimpleDateFormat(java.text.SimpleDateFormat) APIKeyValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO)

Aggregations

TracingSpan (org.wso2.carbon.apimgt.tracing.TracingSpan)13 TracingTracer (org.wso2.carbon.apimgt.tracing.TracingTracer)11 Timer (org.wso2.carbon.metrics.manager.Timer)7 Map (java.util.Map)5 Axis2MessageContext (org.apache.synapse.core.axis2.Axis2MessageContext)5 MethodStats (org.wso2.carbon.apimgt.gateway.MethodStats)5 HashMap (java.util.HashMap)4 SynapseException (org.apache.synapse.SynapseException)2 API (org.wso2.carbon.apimgt.keymgt.model.entity.API)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 XMLStreamException (javax.xml.stream.XMLStreamException)1 JSONObject (net.minidev.json.JSONObject)1 OMElement (org.apache.axiom.om.OMElement)1 AxisFault (org.apache.axis2.AxisFault)1