boolean asChildOf()

in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContextImpl.java [267:328]


    <T> boolean asChildOf(T traceParentHeader, CharAccessor<T> charAccessor) {

        int leadingWs = charAccessor.getLeadingWhitespaceCount(traceParentHeader);
        int trailingWs = charAccessor.getTrailingWhitespaceCount(traceParentHeader);

        try {
            int trimmedLen = Math.max(0, charAccessor.length(traceParentHeader) - leadingWs - trailingWs);
            if (trimmedLen < TEXT_HEADER_EXPECTED_LENGTH) {
                logger.warn("The traceparent header has to be at least 55 chars long, but was '{}'", trimmedLen);
                return false;
            }
            if (noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_TRACE_ID_OFFSET - 1, charAccessor)
                || noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_PARENT_ID_OFFSET - 1, charAccessor)
                || noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_FLAGS_OFFSET - 1, charAccessor)) {
                if (logger.isWarnEnabled()) {
                    logger.warn("The traceparent header has an invalid format: '{}'", charAccessor.asString(traceParentHeader));
                }
                return false;
            }
            if (trimmedLen > TEXT_HEADER_EXPECTED_LENGTH
                && noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_EXPECTED_LENGTH, charAccessor)) {
                if (logger.isWarnEnabled()) {
                    logger.warn("The traceparent header has an invalid format: '{}'", charAccessor.asString(traceParentHeader));
                }
                return false;
            }
            if (charAccessor.containsAtOffset(traceParentHeader, leadingWs, "ff")) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Version ff is not supported");
                }
                return false;
            }
            byte version = charAccessor.readHexByte(traceParentHeader, leadingWs);
            if (version == 0 && trimmedLen > TEXT_HEADER_EXPECTED_LENGTH) {
                if (logger.isWarnEnabled()) {
                    logger.warn("The traceparent header has to be exactly 55 chars long for version 00, but was '{}'", charAccessor.asString(traceParentHeader));
                }
                return false;
            }
            traceId.fromHexString(traceParentHeader, leadingWs + TEXT_HEADER_TRACE_ID_OFFSET, charAccessor);
            if (traceId.isEmpty()) {
                return false;
            }
            parentId.fromHexString(traceParentHeader, leadingWs + TEXT_HEADER_PARENT_ID_OFFSET, charAccessor);
            if (parentId.isEmpty()) {
                return false;
            }
            id.setToRandomValue();
            transactionId.copyFrom(id);
            // TODO don't blindly trust the flags from the caller
            // consider implement rate limiting and/or having a list of trusted sources
            // trace the request if it's either requested or if the parent has recorded it
            flags = charAccessor.readHexByte(traceParentHeader, TEXT_HEADER_FLAGS_OFFSET + leadingWs);
            clock.init();
            return true;
        } catch (IllegalArgumentException e) {
            logger.warn(e.getMessage());
            return false;
        } finally {
            onMutation();
        }
    }