diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/analytics/AnalyticsFilter.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/analytics/AnalyticsFilter.java index de4e237c18..07926f3f91 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/analytics/AnalyticsFilter.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/analytics/AnalyticsFilter.java @@ -26,7 +26,10 @@ import org.apache.logging.log4j.ThreadContext; import org.wso2.carbon.apimgt.common.analytics.collectors.impl.GenericRequestDataCollector; import org.wso2.carbon.apimgt.common.analytics.exceptions.AnalyticsException; +import org.wso2.carbon.apimgt.common.analytics.publishers.dto.Error; +import org.wso2.carbon.apimgt.common.analytics.publishers.dto.enums.FaultCategory; import org.wso2.choreo.connect.enforcer.commons.model.AuthenticationContext; +import org.wso2.choreo.connect.enforcer.commons.model.ChoreoComponentInfo; import org.wso2.choreo.connect.enforcer.commons.model.RequestContext; import org.wso2.choreo.connect.enforcer.config.ConfigHolder; import org.wso2.choreo.connect.enforcer.constants.APIConstants; @@ -108,59 +111,7 @@ public void handleSuccessRequest(RequestContext requestContext) { Utils.setTag(analyticsSpan, APIConstants.LOG_TRACE_ID, ThreadContext.get(APIConstants.LOG_TRACE_ID)); } - String apiName = requestContext.getMatchedAPI().getName(); - String apiVersion = requestContext.getMatchedAPI().getVersion(); - String apiType = requestContext.getMatchedAPI().getApiType(); - AuthenticationContext authContext = AnalyticsUtils.getAuthenticationContext(requestContext); - - requestContext.addMetadataToMap(MetadataConstants.API_ID_KEY, AnalyticsUtils.getAPIId(requestContext)); - requestContext.addMetadataToMap(MetadataConstants.API_CREATOR_KEY, - AnalyticsUtils.setDefaultIfNull(authContext.getApiPublisher())); - requestContext.addMetadataToMap(MetadataConstants.API_NAME_KEY, apiName); - requestContext.addMetadataToMap(MetadataConstants.API_VERSION_KEY, apiVersion); - requestContext.addMetadataToMap(MetadataConstants.API_TYPE_KEY, apiType); - - requestContext.addMetadataToMap(MetadataConstants.API_CREATOR_TENANT_DOMAIN_KEY, - APIConstants.SUPER_TENANT_DOMAIN_NAME); - requestContext.addMetadataToMap(MetadataConstants.API_ENVIRONMENT_ID, - requestContext.getMatchedAPI().getEnvironmentId() == null ? APIConstants.DEFAULT_ENVIRONMENT_NAME : - requestContext.getMatchedAPI().getEnvironmentId()); - - // Default Value would be PRODUCTION - requestContext.addMetadataToMap(MetadataConstants.APP_KEY_TYPE_KEY, - authContext.getKeyType() == null ? APIConstants.API_KEY_TYPE_PRODUCTION : authContext.getKeyType()); - requestContext.addMetadataToMap(MetadataConstants.APP_UUID_KEY, - AnalyticsUtils.setDefaultIfNull(authContext.getApplicationUUID())); - requestContext.addMetadataToMap(MetadataConstants.APP_NAME_KEY, - AnalyticsUtils.setDefaultIfNull(authContext.getApplicationName())); - requestContext.addMetadataToMap(MetadataConstants.APP_OWNER_KEY, - AnalyticsUtils.setDefaultIfNull(authContext.getSubscriber())); - - requestContext.addMetadataToMap(MetadataConstants.CORRELATION_ID_KEY, requestContext.getRequestID()); - requestContext.addMetadataToMap(MetadataConstants.REGION_KEY, - ConfigHolder.getInstance().getEnvVarConfig().getEnforcerRegionId()); - - // As in the matched API, only the resources under the matched resource template are selected. - requestContext.addMetadataToMap(MetadataConstants.API_RESOURCE_TEMPLATE_KEY, - requestContext.getMatchedResourcePath().getPath()); - - requestContext.addMetadataToMap(MetadataConstants.DESTINATION, resolveEndpoint(requestContext)); - - requestContext.addMetadataToMap(MetadataConstants.API_ORGANIZATION_ID, - requestContext.getMatchedAPI().getOrganizationId()); - // Adding UserName and the APIContext - String endUserName = requestContext.getAuthenticationContext().getUsername(); - requestContext.addMetadataToMap(MetadataConstants.API_USER_NAME_KEY, - endUserName == null ? APIConstants.END_USER_UNKNOWN : endUserName); - requestContext.addMetadataToMap(MetadataConstants.API_CONTEXT_KEY, - requestContext.getMatchedAPI().getBasePath()); - requestContext.addMetadataToMap(MetadataConstants.DEPLOYMENT_TYPE, - requestContext.getMatchedAPI().getDeploymentType()); - - // Adding Gateway URL - String gatewayUrl = requestContext.getHeaders().get(GATEWAY_URL); - requestContext.addMetadataToMap(MetadataConstants.GATEWAY_URL, - gatewayUrl); + this.addInsightsMetaData(requestContext); } finally { if (Utils.tracingEnabled()) { analyticsSpanScope.close(); @@ -188,11 +139,13 @@ public void handleFailureRequest(RequestContext requestContext) { ThreadContext.get(APIConstants.LOG_TRACE_ID)); } + this.addInsightsMetaData(requestContext); if (publisher == null) { logger.error("Cannot publish the failure event as analytics publisher is null."); return; } ChoreoFaultAnalyticsProvider provider = new ChoreoFaultAnalyticsProvider(requestContext); + this.addFailureDetailsToInsightsMetaData(requestContext, provider); // To avoid incrementing counter for options call if (provider.getProxyResponseCode() == 200 || provider.getProxyResponseCode() == 204) { return; @@ -212,6 +165,87 @@ public void handleFailureRequest(RequestContext requestContext) { } } + private void addInsightsMetaData(RequestContext requestContext) { + String apiName = requestContext.getMatchedAPI().getName(); + String apiVersion = requestContext.getMatchedAPI().getVersion(); + String apiType = requestContext.getMatchedAPI().getApiType(); + + ChoreoComponentInfo choreoComponentInfo = requestContext.getMatchedAPI().getChoreoComponentInfo(); + String projectId = null; + String componentId = null; + String versionId = null; + if (choreoComponentInfo != null) { + projectId = choreoComponentInfo.getProjectID(); + componentId = choreoComponentInfo.getComponentID(); + versionId = choreoComponentInfo.getVersionID(); + } + + AuthenticationContext authContext = AnalyticsUtils.getAuthenticationContext(requestContext); + + requestContext.addMetadataToMap(MetadataConstants.API_PROJECT_ID_KEY, projectId); + requestContext.addMetadataToMap(MetadataConstants.API_COMPONENT_ID_KEY, componentId); + requestContext.addMetadataToMap(MetadataConstants.API_VERSION_ID_KEY, versionId); + + requestContext.addMetadataToMap(MetadataConstants.API_ID_KEY, AnalyticsUtils.getAPIId(requestContext)); + requestContext.addMetadataToMap(MetadataConstants.API_CREATOR_KEY, + AnalyticsUtils.setDefaultIfNull(authContext.getApiPublisher())); + requestContext.addMetadataToMap(MetadataConstants.API_NAME_KEY, apiName); + requestContext.addMetadataToMap(MetadataConstants.API_VERSION_KEY, apiVersion); + requestContext.addMetadataToMap(MetadataConstants.API_TYPE_KEY, apiType); + + requestContext.addMetadataToMap(MetadataConstants.API_CREATOR_TENANT_DOMAIN_KEY, + APIConstants.SUPER_TENANT_DOMAIN_NAME); + requestContext.addMetadataToMap(MetadataConstants.API_ENVIRONMENT_ID, + requestContext.getMatchedAPI().getEnvironmentId() == null ? APIConstants.DEFAULT_ENVIRONMENT_NAME : + requestContext.getMatchedAPI().getEnvironmentId()); + + // Default Value would be PRODUCTION + requestContext.addMetadataToMap(MetadataConstants.APP_KEY_TYPE_KEY, + authContext.getKeyType() == null ? APIConstants.API_KEY_TYPE_PRODUCTION : authContext.getKeyType()); + requestContext.addMetadataToMap(MetadataConstants.APP_UUID_KEY, + AnalyticsUtils.setDefaultIfNull(authContext.getApplicationUUID())); + requestContext.addMetadataToMap(MetadataConstants.APP_NAME_KEY, + AnalyticsUtils.setDefaultIfNull(authContext.getApplicationName())); + requestContext.addMetadataToMap(MetadataConstants.APP_OWNER_KEY, + AnalyticsUtils.setDefaultIfNull(authContext.getSubscriber())); + + requestContext.addMetadataToMap(MetadataConstants.CORRELATION_ID_KEY, requestContext.getRequestID()); + requestContext.addMetadataToMap(MetadataConstants.REGION_KEY, + ConfigHolder.getInstance().getEnvVarConfig().getEnforcerRegionId()); + + // As in the matched API, only the resources under the matched resource template are selected. + requestContext.addMetadataToMap(MetadataConstants.API_RESOURCE_TEMPLATE_KEY, + requestContext.getMatchedResourcePath().getPath()); + + requestContext.addMetadataToMap(MetadataConstants.DESTINATION, resolveEndpoint(requestContext)); + + requestContext.addMetadataToMap(MetadataConstants.API_ORGANIZATION_ID, + requestContext.getMatchedAPI().getOrganizationId()); + // Adding UserName and the APIContext + String endUserName = requestContext.getAuthenticationContext().getUsername(); + requestContext.addMetadataToMap(MetadataConstants.API_USER_NAME_KEY, + endUserName == null ? APIConstants.END_USER_UNKNOWN : endUserName); + requestContext.addMetadataToMap(MetadataConstants.API_CONTEXT_KEY, + requestContext.getMatchedAPI().getBasePath()); + requestContext.addMetadataToMap(MetadataConstants.DEPLOYMENT_TYPE, + requestContext.getMatchedAPI().getDeploymentType()); + + // Adding Gateway URL + String gatewayUrl = requestContext.getHeaders().get(GATEWAY_URL); + requestContext.addMetadataToMap(MetadataConstants.GATEWAY_URL, + gatewayUrl); + } + + private void addFailureDetailsToInsightsMetaData(RequestContext requestContext, + ChoreoFaultAnalyticsProvider provider) { + FaultCategory faultCategory = provider.getFaultType(); + Error error = provider.getError(faultCategory); + + requestContext.addMetadataToMap(MetadataConstants.INSIGHTS_ERROR_TYPE, faultCategory.toString()); + requestContext.addMetadataToMap(MetadataConstants.INSIGHTS_ERROR_CODE, String.valueOf(error.getErrorCode())); + requestContext.addMetadataToMap(MetadataConstants.INSIGHTS_ERROR_MESSAGE, error.getErrorMessage().toString()); + } + private static AnalyticsEventPublisher loadAnalyticsPublisher(String className, boolean isChoreoDeployment) { // For the choreo deployment, class name need not to be provided. diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java index d67c0e0d34..b6d4b76d17 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java @@ -20,6 +20,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.wso2.choreo.connect.discovery.api.Api; +import org.wso2.choreo.connect.discovery.api.ChoreoComponentInfo; import org.wso2.choreo.connect.discovery.api.Operation; import org.wso2.choreo.connect.discovery.api.Resource; import org.wso2.choreo.connect.discovery.api.Scopes; @@ -146,6 +147,9 @@ public String init(Api api) { api.getEndpointSecurity().getSandBoxSecurityInfo())); } + org.wso2.choreo.connect.enforcer.commons.model.ChoreoComponentInfo choreoComponentInfo = getChoreoComponentInfo( + api); + this.apiLifeCycleState = api.getApiLifeCycleState(); this.apiConfig = new APIConfig.Builder(name).uuid(api.getId()).vhost(vhost).basePath(basePath).version(version) .resources(resources).apiType(apiType).apiLifeCycleState(apiLifeCycleState).tier(api.getTier()) @@ -156,12 +160,29 @@ public String init(Api api) { .enableBackendJWT(api.getEnableBackendJWT()).backendJWTConfiguration(backendJWTConfiguration) .deploymentType(api.getDeploymentType()) .environmentId(api.getEnvironmentId()) - .environmentName(api.getEnvironmentName()).build(); + .environmentName(api.getEnvironmentName()) + .choreoComponentInfo(choreoComponentInfo) + .build(); initFilters(); return basePath; } + private static org.wso2.choreo.connect.enforcer.commons.model.ChoreoComponentInfo getChoreoComponentInfo( + Api api) { + ChoreoComponentInfo infoProto = api.getChoreoComponentInfo(); + org.wso2.choreo.connect.enforcer.commons.model.ChoreoComponentInfo choreoComponentInfo = + new org.wso2.choreo.connect.enforcer.commons.model.ChoreoComponentInfo(); + if (infoProto == null) { + return choreoComponentInfo; + } + choreoComponentInfo.setOrganizationID(infoProto.getOrganizationID()); + choreoComponentInfo.setProjectID(infoProto.getProjectID()); + choreoComponentInfo.setComponentID(infoProto.getComponentID()); + choreoComponentInfo.setVersionID(infoProto.getVersionID()); + return choreoComponentInfo; + } + @Override public ResponseObject process(RequestContext requestContext) { ResponseObject responseObject = new ResponseObject(requestContext.getRequestID()); @@ -206,8 +227,8 @@ public ResponseObject process(RequestContext requestContext) { } if (analyticsEnabled && !FilterUtils.isSkippedAnalyticsFaultEvent(responseObject.getErrorCode())) { AnalyticsFilter.getInstance().handleFailureRequest(requestContext); - responseObject.setMetaDataMap(new HashMap<>(0)); } + responseObject.setMetaDataMap(requestContext.getMetadataMap()); } return responseObject; diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/MetadataConstants.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/MetadataConstants.java index acc43064c7..8f48f5566e 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/MetadataConstants.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/MetadataConstants.java @@ -25,6 +25,14 @@ public class MetadataConstants { public static final String EXT_AUTH_METADATA_CONTEXT_KEY = "envoy.filters.http.ext_authz"; public static final String WSO2_METADATA_PREFIX = "x-wso2-"; + + public static final String API_PROJECT_ID_KEY = WSO2_METADATA_PREFIX + "project-id"; + public static final String API_COMPONENT_ID_KEY = WSO2_METADATA_PREFIX + "component-id"; + public static final String API_VERSION_ID_KEY = WSO2_METADATA_PREFIX + "version-id"; + public static final String INSIGHTS_ERROR_TYPE = WSO2_METADATA_PREFIX + "error-type"; + public static final String INSIGHTS_ERROR_CODE = WSO2_METADATA_PREFIX + "error-code"; + public static final String INSIGHTS_ERROR_MESSAGE = WSO2_METADATA_PREFIX + "error-message"; + public static final String API_ID_KEY = WSO2_METADATA_PREFIX + "api-id"; public static final String API_CREATOR_KEY = WSO2_METADATA_PREFIX + "api-creator"; public static final String API_NAME_KEY = WSO2_METADATA_PREFIX + "api-name";