Java Code Examples for com.nike.internal.util.StringUtils#isBlank()

The following examples show how to use com.nike.internal.util.StringUtils#isBlank() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RiposteWingtipsServerTagAdapter.java    From riposte with Apache License 2.0 6 votes vote down vote up
@Nullable
@Override
public String getRequestUriPathTemplate(
    @Nullable RequestInfo<?> request, @Nullable ResponseInfo<?> response
) {
    if (request == null) {
        return null;
    }

    String pathTemplate = request.getPathTemplate();
    if (StringUtils.isBlank(pathTemplate)) {
        return null;
    }

    return pathTemplate;
}
 
Example 2
Source File: HttpTagAndSpanNamingStrategy.java    From wingtips with Apache License 2.0 6 votes vote down vote up
/**
 * A helper method that can be used by subclasses for putting a tag value on the given span (via {@link
 * Span#putTag(String, String)}) if and only if the tag value is not null and its {@link Object#toString()} is not
 * blank (according to {@link StringUtils#isBlank(CharSequence)}).
 *
 * @param span The span to tag - should never be null.
 * @param tagKey The key to use when calling {@link Span#putTag(String, String)} - should never be null.
 * @param tagValue The tag value to use if and only if it is not null and its {@link Object#toString()} is not
 * blank.
 */
protected void putTagIfValueIsNotBlank(
    @NotNull Span span,
    @NotNull String tagKey,
    @Nullable Object tagValue
) {
    //noinspection ConstantConditions
    if (tagValue == null || span == null || tagKey == null) {
        return;
    }

    // tagValue is not null. Convert to string and check for blank.
    String tagValueString = tagValue.toString();

    if (StringUtils.isBlank(tagValueString)) {
        return;
    }

    // tagValue is not blank. Add it to the given span.
    span.putTag(tagKey, tagValueString);
}
 
Example 3
Source File: WingtipsSpringBoot2WebfluxConfiguration.java    From wingtips with Apache License 2.0 6 votes vote down vote up
protected @Nullable HttpTagAndSpanNamingAdapter<ServerWebExchange, ServerHttpResponse> extractTagAndNamingAdapter(
    WingtipsSpringBoot2WebfluxProperties props
) {
    String adapterName = props.getServerSideSpanTaggingAdapter();

    if (StringUtils.isBlank(adapterName)) {
        // Nothing specified, so return null to use the default.
        return null;
    }

    // There are no shortnames for the adapter like there are for strategy. Try instantiating by classname
    try {
        //noinspection unchecked
        return (HttpTagAndSpanNamingAdapter<ServerWebExchange, ServerHttpResponse>)
            Class.forName(adapterName).newInstance();
    }
    catch (Exception ex) {
        // Couldn't instantiate by interpreting it as a class name. Return null so the default gets used.
        logger.warn(
            "Unable to match tagging adapter \"{}\". "
            + "Using the default adapter (SpringWebfluxServerRequestTagAdapter)",
            adapterName, ex
        );
        return null;
    }
}
 
Example 4
Source File: RiposteWingtipsNettyClientTagAdapter.java    From riposte with Apache License 2.0 5 votes vote down vote up
@Nullable
@Override
public String getRequestPath(@Nullable HttpRequest request) {
    if (request == null) {
        return null;
    }

    String result = HttpUtils.extractPath(request.uri());
    if (StringUtils.isBlank(result)) {
        return null;
    }

    return result;
}
 
Example 5
Source File: WingtipsSpringBoot2WebfluxConfiguration.java    From wingtips with Apache License 2.0 5 votes vote down vote up
protected @Nullable HttpTagAndSpanNamingStrategy<ServerWebExchange, ServerHttpResponse> extractTagAndNamingStrategy(
    WingtipsSpringBoot2WebfluxProperties props
) {
    String strategyName = props.getServerSideSpanTaggingStrategy();

    if (StringUtils.isBlank(strategyName)) {
        // Nothing specified, so return null to use the default.
        return null;
    }

    // Check for a short-name match first.
    if ("zipkin".equalsIgnoreCase(strategyName)) {
        return ZipkinHttpTagStrategy.getDefaultInstance();
    }

    if("opentracing".equalsIgnoreCase(strategyName)) {
        return OpenTracingHttpTagStrategy.getDefaultInstance();
    }

    if("none".equalsIgnoreCase(strategyName) || "noop".equalsIgnoreCase(strategyName)) {
        return NoOpHttpTagStrategy.getDefaultInstance();
    }

    // At this point there was no short-name match. Try instantiating it by classname.
    try {
        //noinspection unchecked
        return (HttpTagAndSpanNamingStrategy<ServerWebExchange, ServerHttpResponse>)
            Class.forName(strategyName).newInstance();
    }
    catch (Exception ex) {
        // Couldn't instantiate by interpreting it as a class name. Return null so the default gets used.
        logger.warn("Unable to match tagging strategy \"{}\". Using the default strategy (Zipkin)",
                    strategyName, ex);
        return null;
    }
}
 
Example 6
Source File: AsyncHttpClientHelperTagAdapter.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Nullable
@Override
public String getRequestPath(@Nullable RequestBuilderWrapper request) {
    if (request == null) {
        return null;
    }

    String result = request.getUrl();
    if (StringUtils.isBlank(result)) {
        return null;
    }

    // Chop out the query string (if any).
    result = HttpUtils.extractPath(result);

    // If it starts with '/' then there's nothing left for us to do - it's already the path.
    if (result.startsWith("/")) {
        return result;
    }

    // Doesn't start with '/'. We expect it to start with http at this point.
    if (!result.toLowerCase().startsWith("http")) {
        // Didn't start with http. Not sure what to do with this at this point, so return null.
        return null;
    }

    // It starts with http. Chop out the scheme and host/port.
    int schemeColonAndDoubleSlashIndex = result.indexOf("://");
    if (schemeColonAndDoubleSlashIndex < 0) {
        // It didn't have a colon-double-slash after the scheme. Not sure what to do at this point, so return null.
        return null;
    }

    int firstSlashIndexAfterSchemeDoubleSlash = result.indexOf('/', (schemeColonAndDoubleSlashIndex + 3));
    if (firstSlashIndexAfterSchemeDoubleSlash < 0) {
        // No other slashes after the scheme colon-double-slash, so no real path. The path at this point is
        //      effectively "/".
        return "/";
    }

    return result.substring(firstSlashIndexAfterSchemeDoubleSlash);
}
 
Example 7
Source File: AsyncHttpClientHelperTagAdapter.java    From riposte with Apache License 2.0 4 votes vote down vote up
@Nullable
@Override
public String getRequestPath(@Nullable RequestBuilderWrapper request) {
    if (request == null) {
        return null;
    }

    String result = request.getUrl();
    if (StringUtils.isBlank(result)) {
        return null;
    }

    // Chop out the query string (if any).
    result = HttpUtils.extractPath(result);

    // If it starts with '/' then there's nothing left for us to do - it's already the path.
    if (result.startsWith("/")) {
        return result;
    }

    // Doesn't start with '/'. We expect it to start with http at this point.
    if (!result.toLowerCase().startsWith("http")) {
        // Didn't start with http. Not sure what to do with this at this point, so return null.
        return null;
    }

    // It starts with http. Chop out the scheme and host/port.
    int schemeColonAndDoubleSlashIndex = result.indexOf("://");
    if (schemeColonAndDoubleSlashIndex < 0) {
        // It didn't have a colon-double-slash after the scheme. Not sure what to do at this point, so return null.
        return null;
    }

    int firstSlashIndexAfterSchemeDoubleSlash = result.indexOf('/', (schemeColonAndDoubleSlashIndex + 3));
    if (firstSlashIndexAfterSchemeDoubleSlash < 0) {
        // No other slashes after the scheme colon-double-slash, so no real path. The path at this point is
        //      effectively "/".
        return "/";
    }

    return result.substring(firstSlashIndexAfterSchemeDoubleSlash);
}
 
Example 8
Source File: RequestTracingFilter.java    From wingtips with Apache License 2.0 4 votes vote down vote up
/**
 * Uses the given {@code strategyName} to determine and generate the {@link HttpTagAndSpanNamingStrategy} that
 * should be used by this instance. This method looks for the following short names first:
 * <ul>
 *     <li>
 *         {@code ZIPKIN} (or a null/blank {@code strategyName}) - causes {@link #getZipkinHttpTagStrategy()} to be
 *         returned
 *     </li>
 *     <li>{@code OPENTRACING} - causes {@link #getOpenTracingHttpTagStrategy()} to be returned</li>
 *     <li>{@code NONE} - causes {@link #getNoOpTagStrategy()} to be returned</li>
 * </ul>
 *
 * If {@code strategyName} does not match any of those short names, then it is assumed to be a fully qualified
 * class name. {@link Class#forName(String)} will be used to get the class, and then it will be instantiated
 * via {@link Class#newInstance()} and cast to the necessary {@link HttpTagAndSpanNamingStrategy}. This means a
 * class instantiated this way must have a default no-arg constructor and must extend {@link
 * HttpTagAndSpanNamingStrategy}.
 *
 * <p>NOTE: This method may throw a variety of exceptions if {@code strategyName} does not match a short name,
 * and {@link Class#forName(String)} or {@link Class#newInstance()} fails to instantiate it as a fully qualified
 * class name (or if it was instantiated but couldn't be cast to the necessary {@link
 * HttpTagAndSpanNamingStrategy}). Callers should account for this possibility and have a reasonable default
 * fallback if an exception is thrown.
 *
 * @param strategyName The short name or fully qualified class name of the {@link HttpTagAndSpanNamingStrategy}
 * that should be used by this instance. If this is null or blank, then {@link #getZipkinHttpTagStrategy()} will
 * be returned.
 * @return The {@link HttpTagAndSpanNamingStrategy} that should be used by this instance.
 */
@SuppressWarnings("unchecked")
protected HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> getTagStrategyFromName(
    String strategyName
) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ClassCastException {
    // Default is the Zipkin strategy
    if (StringUtils.isBlank(strategyName) || "zipkin".equalsIgnoreCase(strategyName)) {
        return getZipkinHttpTagStrategy();
    }

    if("opentracing".equalsIgnoreCase(strategyName)) {
        return getOpenTracingHttpTagStrategy();
    }

    if("none".equalsIgnoreCase(strategyName) || "noop".equalsIgnoreCase(strategyName)) {
        return getNoOpTagStrategy();
    }

    // At this point there was no short-name match. Try instantiating it by classname.
    return (HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse>)
        Class.forName(strategyName).newInstance();
}
 
Example 9
Source File: RequestTracingFilterTest.java    From wingtips with Apache License 2.0 4 votes vote down vote up
@DataProvider(value = {
    "ZIPKIN",
    "Zipkin",
    "opentracing",
    "OpenTracing",
    "NONE",
    "NoNe",
    "NOOP",
    "null",
    "",
    " ",
    " \t\r\n  "
})
@Test
public void getTagStrategyFromName_returns_expected_strategies_for_known_short_names(
    String knownStrategyShortName
) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
    // given
    RequestTracingFilter filterSpy = spy(new RequestTracingFilter());
    HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> zipkinStrategyMock =
        mock(HttpTagAndSpanNamingStrategy.class);
    HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> openTracingStrategyMock =
        mock(HttpTagAndSpanNamingStrategy.class);
    HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> noOpStrategyMock =
        mock(HttpTagAndSpanNamingStrategy.class);

    doReturn(zipkinStrategyMock).when(filterSpy).getZipkinHttpTagStrategy();
    doReturn(openTracingStrategyMock).when(filterSpy).getOpenTracingHttpTagStrategy();
    doReturn(noOpStrategyMock).when(filterSpy).getNoOpTagStrategy();

    // when
    HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse>
        result = filterSpy.getTagStrategyFromName(knownStrategyShortName);

    // then

    // Default is Zipkin
    if (StringUtils.isBlank(knownStrategyShortName) || "zipkin".equalsIgnoreCase(knownStrategyShortName)) {
        assertThat(result).isSameAs(zipkinStrategyMock);
    }
    else if ("opentracing".equalsIgnoreCase(knownStrategyShortName)) {
        assertThat(result).isSameAs(openTracingStrategyMock);
    }
    else if ("none".equalsIgnoreCase(knownStrategyShortName) || "noop".equalsIgnoreCase(knownStrategyShortName)) {
        assertThat(result).isSameAs(noOpStrategyMock);
    }
}
 
Example 10
Source File: HttpRequestTracingUtils.java    From wingtips with Apache License 2.0 4 votes vote down vote up
/**
 * This method generates a span name from the given arguments that is "safe" for visualization/analytics systems
 * that expect low cardinality span names. The logic in this method mimics what Zipkin does for its span names.
 *
 * <p>The returned span name format will be the HTTP method followed by a space, and then the path template
 * (if one exists). If the HTTP response status code is 3xx, then the path template is replaced with "redirected",
 * and if the status code is 404 then the path template is replaced with "not_found". If the HTTP method is null
 * or blank, then "UNKNOWN_HTTP_METHOD" will be used for the HTTP method in the returned span name.
 *
 * <p>Examples that show these rules:
 * <ul>
 *     <li>
 *         HTTP method "GET", path template "/some/path/tmplt", and response status code not 3xx and not 404:
 *         {@code "GET /some/path/tmplt"}
 *     </li>
 *     <li>
 *         HTTP method "GET", and response status code 3xx:
 *         {@code "GET redirected"}
 *     </li>
 *     <li>
 *         HTTP method "GET", and response status code 404:
 *         {@code "GET not_found"}
 *     </li>
 *     <li>
 *         HTTP method "GET", null or blank path template, and response status code not 3xx and not 404:
 *         {@code "GET"}
 *     </li>
 *     <li>
 *         Null or blank HTTP method, path template "/some/path/tmplt", and response status code not 3xx and not
 *         404: {@code "UNKNOWN_HTTP_METHOD /some/path/tmplt"}
 *     </li>
 *     <li>
 *         Null or blank HTTP method, and response status code 3xx:
 *         {@code "UNKNOWN_HTTP_METHOD redirected"}
 *     </li>
 *     <li>
 *         Null or blank HTTP method, and response status code 404:
 *         {@code "UNKNOWN_HTTP_METHOD not_found"}
 *     </li>
 *     <li>
 *         Null or blank HTTP method, null or blank path template, and response status code not 3xx and not 404:
 *         {@code "UNKNOWN_HTTP_METHOD"}
 *     </li>
 * </ul>
 *
 * @param requestHttpMethod The request HTTP method - can be null. If you pass null, then "UNKNOWN_HTTP_METHOD"
 * will be used for the HTTP method.
 * @param pathTemplate The *low-cardinality* URI path template for the request (e.g. {@code /foo/:id} rather than
 * {@code /foo/12345}) - can be null. If you pass null, then path template will be omitted.
 * @param responseStatusCode The HTTP response status code associated with the request - can be null. If this
 * is not null and represents a 3xx response, then "redirected" will be used as the path template to avoid high
 * cardinality issues. Similarly, a 404 status code will result in "not_found" being used as the path template.
 * @return The concatenation of HTTP method, followed by a space, followed by the path template. See the rest of
 * this method's javadocs for details on how null arguments and/or the HTTP response status code can adjust the
 * returned value.
 */
public static @NotNull String generateSafeSpanName(
    @Nullable String requestHttpMethod,
    @Nullable String pathTemplate,
    @Nullable Integer responseStatusCode
) {
    if (StringUtils.isBlank(requestHttpMethod)) {
        requestHttpMethod = "UNKNOWN_HTTP_METHOD";
    }

    if (responseStatusCode != null) {
        if (responseStatusCode / 100 == 3) {
            return requestHttpMethod + " redirected";
        }
        else if (responseStatusCode == 404) {
            return requestHttpMethod + " not_found";
        }
    }

    return (StringUtils.isBlank(pathTemplate))
           ? requestHttpMethod
           : requestHttpMethod + " " + pathTemplate;
}
 
Example 11
Source File: HttpRequestTracingUtils.java    From wingtips with Apache License 2.0 4 votes vote down vote up
/**
 * A helper method for returning a reasonable fallback {@link Span#getSpanName()} for a span around an HTTP
 * request - good for when you need a span name but {@link
 * com.nike.wingtips.tags.HttpTagAndSpanNamingStrategy#getInitialSpanName(Object, HttpTagAndSpanNamingAdapter)}
 * returns null.
 *
 * <p>This method returns {@code [PREFIX]-[HTTP_METHOD]}, or simply {@code [HTTP_METHOD]} if prefix is null or
 * blank. If the given HTTP method is null or blank, then "UNKNOWN_HTTP_METHOD" will be used. This method will
 * therefore never return null.
 *
 * <p>For example, if you pass "downstream_call", and "GET" to this method, then it would return
 * {@code "downstream_call-GET"}.
 *
 * <p>NOTE: This span name format is not required for anything - you can name spans anything you want. This
 * method is just here as a convenience. You should be aware, though, that some distributed tracing visualization
 * and analysis systems expect span names to be low cardinality, so adding the raw URL to the span name is
 * discouraged (and enforced by this method only taking a presumably-low-cardinality prefix and
 * definitely-low-cardinality HTTP method). Adding the low-cardinality path template is a good idea
 * (e.g. {@code /foo/:id} instead of {@code /foo/12345}), which is what {@link
 * HttpTagAndSpanNamingAdapter#getRequestUriPathTemplate(Object, Object)} is for, and which itself is used by
 * the various naming methods of {@link com.nike.wingtips.tags.HttpTagAndSpanNamingStrategy}. So this method
 * is really only meant to be used as a fallback in case the naming strategy/adapter returns null.
 *
 * <p>ALSO NOTE: The {@link #generateSafeSpanName(Object, Object, HttpTagAndSpanNamingAdapter)} and
 * {@link #generateSafeSpanName(String, String, Integer)} methods are similar to this one, but meant for a slightly
 * different use case where you have access to things like the request, response, URI/path template, and/or
 * HTTP response status code. Use those methods where possible - this method is meant as a last resort.
 *
 * @param prefix The prefix that should be added first. This can be null - if this is null then the result will
 * not contain any prefix and will be based solely on httpMethod.
 * @param httpMethod The HTTP method for the downstream call. This can be null (although it's not recommended) -
 * if this is null or blank then "UNKNOWN_HTTP_METHOD" will be used instead.
 * @return The fallback span name for the given prefix and HTTP method - never returns null.
 */
public static @NotNull String getFallbackSpanNameForHttpRequest(
    @Nullable String prefix,
    @Nullable String httpMethod
) {
    if (StringUtils.isBlank(prefix)) {
        prefix = null;
    }

    if (StringUtils.isBlank(httpMethod)) {
        httpMethod = "UNKNOWN_HTTP_METHOD";
    }

    return (prefix == null)
           ? httpMethod
           : prefix + "-" + httpMethod;
}
 
Example 12
Source File: RequestTracingFilter.java    From wingtips with Apache License 2.0 3 votes vote down vote up
/**
 * Uses the given {@code adapterName} to determine and generate the {@link HttpTagAndSpanNamingAdapter} that
 * should be used by this instance.
 *
 * <p>If {@code adapterName} is null or blank, then {@link #getDefaultTagAdapter()} will be returned. Otherwise,
 * it is assumed to be a fully qualified class name. {@link Class#forName(String)} will be used to get the class,
 * and then it will be instantiated via {@link Class#newInstance()} and cast to the necessary
 * {@link HttpTagAndSpanNamingAdapter}. This means a class instantiated this way must have a default no-arg
 * constructor and must extend {@link HttpTagAndSpanNamingAdapter}.
 *
 * <p>NOTE: This method may throw a variety of exceptions if {@link Class#forName(String)} or
 * {@link Class#newInstance()} fails to instantiate it as a fully qualified class name (or if it was instantiated
 * but couldn't be cast to the necessary {@link HttpTagAndSpanNamingAdapter}). Callers should account for this
 * possibility and have a reasonable default fallback if an exception is thrown.
 *
 * @param adapterName The fully qualified class name of the {@link HttpTagAndSpanNamingAdapter} that should be
 * used by this instance, or pass null/blank if you want {@link #getDefaultTagAdapter()} to be returned.
 * @return The {@link HttpTagAndSpanNamingAdapter} that should be used by this instance.
 */
@SuppressWarnings("unchecked")
protected HttpTagAndSpanNamingAdapter<HttpServletRequest, HttpServletResponse> getTagAdapterFromName(
    String adapterName
) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    // Default is the ServletRequestTagAdapter
    if (StringUtils.isBlank(adapterName)) {
        return getDefaultTagAdapter();
    }

    // There are no shortnames for the adapter like there are for strategy. Try instantiating by classname
    return (HttpTagAndSpanNamingAdapter<HttpServletRequest, HttpServletResponse>)
        Class.forName(adapterName).newInstance();
}
 
Example 13
Source File: HttpTagAndSpanNamingAdapter.java    From wingtips with Apache License 2.0 3 votes vote down vote up
/**
 * By default this method uses a combination of {@link #getSpanNamePrefix(Object)} and {@link
 * HttpRequestTracingUtils#generateSafeSpanName(Object, Object, HttpTagAndSpanNamingAdapter)} to generate a name.
 * You can override this method if you need different behavior.
 *
 * @param request The request object to be inspected - <b>this may be null!</b>
 *
 * @return The initial span name that this adapter wants to use for a span around the given request, or null
 * if this adapter can't (or doesn't want to) come up with a name. Callers should always check for a null return
 * value, and come up with a reasonable fallback name in that case.
 */
public @Nullable String getInitialSpanName(@Nullable REQ request) {
    String prefix = getSpanNamePrefix(request);

    String defaultSpanName = HttpRequestTracingUtils.generateSafeSpanName(request, null, this);

    return (StringUtils.isBlank(prefix))
           ? defaultSpanName
           : prefix + "-" + defaultSpanName;
}
 
Example 14
Source File: HttpTagAndSpanNamingAdapter.java    From wingtips with Apache License 2.0 3 votes vote down vote up
/**
 * By default this method uses a combination of {@link #getSpanNamePrefix(Object)} and {@link
 * HttpRequestTracingUtils#generateSafeSpanName(Object, Object, HttpTagAndSpanNamingAdapter)} to generate a name.
 * You can override this method if you need different behavior.
 *
 * @param request The request object to be inspected - <b>this may be null!</b>
 * @param response The response object to be inspected - <b>this may be null!</b>
 *
 * @return The final span name that this adapter wants to use for a span around the given request, or null
 * if this adapter can't (or doesn't want to) come up with a name. Callers should always check for a null return
 * value, and should not change the preexisting initial span name if this returns null.
 */
public @Nullable String getFinalSpanName(@Nullable REQ request, @Nullable RES response) {
    String prefix = getSpanNamePrefix(request);

    String defaultSpanName = HttpRequestTracingUtils.generateSafeSpanName(request, response, this);

    return (StringUtils.isBlank(prefix))
           ? defaultSpanName
           : prefix + "-" + defaultSpanName;
}
 
Example 15
Source File: SpanMutator.java    From wingtips with Apache License 2.0 3 votes vote down vote up
/**
 * Changes the given span's {@link Span#getSpanName()} to the given {@code newName}. Does nothing if the given
 * span is null, or if the given {@code newName} is null or blank.
 *
 * <p>The main reason this method exists at all is to facilitate situations where full context for the correct
 * span name isn't known at the time of span creation. For example, for HTTP spans we'd like the span name to
 * include the HTTP route (URL path template), but this information usually isn't known until after the request
 * has been processed. So this method allows for the span name to be set to something initially, and then changed
 * later when the data for the final span name is available.
 * 
 * @param span The span to mutate. You can pass null, although nothing will happen if you do.
 * @param newName The new span name to set on the given span. You can pass null or blank string, although nothing
 * will happen if you do (the span's name will not be changed in these cases).
 */
public static void changeSpanName(@Nullable Span span, @Nullable String newName) {
    if (span == null) {
        return;
    }

    if (StringUtils.isBlank(newName)) {
        return;
    }

    span.setSpanName(newName);
}