001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server.tracing; 018 019import org.apache.juneau.rest.server.*; 020 021/** 022 * Default {@link TracerHook} implementation that opens no spans and records nothing. 023 * 024 * <p> 025 * Used whenever no consumer-provided {@code TracerHook} bean is reachable from the 026 * {@code RestContext}'s bean store. Ensures the {@link TracerHook} contract is always satisfied 027 * — the framework can call {@link #startSpan(RestRequest)} unconditionally without a 028 * null-check, and the returned {@link NoOpScope} satisfies the close-in-finally contract with 029 * zero allocations. 030 * 031 * <p> 032 * Both {@link #INSTANCE} and {@link NoOpScope#INSTANCE} are process-wide singletons; the 033 * {@link #startSpan(RestRequest)} method returns the same scope reference for every call and JIT-inlines 034 * the no-op setters / close to empty method bodies. 035 * 036 * @since 10.0.0 037 */ 038@SuppressWarnings({ 039 "java:S6548" // Intentional process-wide no-op singleton; the Singleton pattern is required to satisfy the TracerHook SPI contract with zero allocation. 040}) 041public final class NoOpTracerHook implements TracerHook { 042 043 /** Process-wide singleton instance. */ 044 public static final NoOpTracerHook INSTANCE = new NoOpTracerHook(); 045 046 private NoOpTracerHook() {} 047 048 @Override /* TracerHook */ 049 public Scope startSpan(RestRequest request) { 050 return NoOpScope.INSTANCE; 051 } 052 053 /** 054 * No-op {@link Scope} returned by {@link NoOpTracerHook}. 055 * 056 * <p> 057 * Drops every status, error, and close transition on the floor. Public so user code that wants to 058 * fall back to the no-op behaviour from a custom {@link TracerHook} (for example, when the 059 * incoming trace context is unparseable) can return {@link #INSTANCE} instead of implementing a 060 * private equivalent. 061 */ 062 @SuppressWarnings({ 063 "resource" // Singleton; intentionally held for the process lifetime. 064 }) 065 public static final class NoOpScope implements Scope { 066 067 /** Process-wide singleton instance. */ 068 public static final NoOpScope INSTANCE = new NoOpScope(); 069 070 private NoOpScope() {} 071 072 @Override /* Scope */ 073 public void setStatusCode(int statusCode) { 074 // Intentionally empty. 075 } 076 077 @Override /* Scope */ 078 public void setError(Throwable error) { 079 // Intentionally empty. 080 } 081 082 @Override /* Scope */ 083 public void close() { 084 // Intentionally empty. 085 } 086 } 087}