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.health; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.util.*; 022 023/** 024 * Component health result returned from a {@link HealthIndicator}. 025 * 026 * @since 10.0.0 027 */ 028public final class Health { 029 030 private final String name; 031 private final HealthStatus status; 032 private final Map<String,Object> details; 033 private final Throwable error; 034 035 private Health(Builder b) { 036 this.name = b.name; 037 this.status = b.status; 038 this.details = u(cp(b.details)); 039 this.error = b.error; 040 } 041 042 /** 043 * Creates an {@link HealthStatus#UP} builder. 044 * 045 * @param name Component name. Must not be <jk>null</jk> or empty. 046 * @return A new builder. 047 */ 048 public static Builder up(String name) { 049 return new Builder(name, HealthStatus.UP, null); 050 } 051 052 /** 053 * Creates an {@link HealthStatus#DOWN} builder. 054 * 055 * @param name Component name. Must not be <jk>null</jk> or empty. 056 * @param error Optional error causing the down state. Can be <jk>null</jk> (no error is recorded). 057 * @return A new builder. 058 */ 059 public static Builder down(String name, Throwable error) { 060 return new Builder(name, HealthStatus.DOWN, error); 061 } 062 063 /** 064 * Creates an {@link HealthStatus#UNKNOWN} builder. 065 * 066 * @param name Component name. Must not be <jk>null</jk> or empty. 067 * @return A new builder. 068 */ 069 public static Builder unknown(String name) { 070 return new Builder(name, HealthStatus.UNKNOWN, null); 071 } 072 073 /** @return Component name. */ 074 public String getName() { return name; } 075 /** @return Health status. */ 076 public HealthStatus getStatus() { return status; } 077 /** @return Structured details map. */ 078 public Map<String,Object> getDetails() { return details; } 079 /** @return Optional error. */ 080 public Throwable getError() { return error; } 081 082 /** 083 * Builder for {@link Health}. 084 */ 085 public static final class Builder { 086 private final String name; 087 private final HealthStatus status; 088 private final Map<String,Object> details = m(); 089 private Throwable error; 090 091 private Builder(String name, HealthStatus status, Throwable error) { 092 reqnn("name", name); 093 if (name.isEmpty()) 094 throw new IllegalArgumentException("Argument 'name' cannot be empty."); 095 this.name = name; 096 this.status = Objects.requireNonNull(status, "status"); 097 this.error = error; 098 } 099 100 /** 101 * Adds a structured detail. 102 * 103 * @param key Detail key. Must not be <jk>null</jk> or empty. 104 * @param value Detail value. Can be <jk>null</jk> (the detail is recorded with a <jk>null</jk> value). 105 * @return This builder. 106 */ 107 public Builder detail(String key, Object value) { 108 reqnn("key", key); 109 if (key.isEmpty()) 110 throw new IllegalArgumentException("Argument 'key' cannot be empty."); 111 details.put(key, value); 112 return this; 113 } 114 115 /** 116 * Overrides the error attached to this result. 117 * 118 * @param value The throwable. Can be <jk>null</jk> (clears the error). 119 * @return This builder. 120 */ 121 public Builder error(Throwable value) { 122 error = value; 123 return this; 124 } 125 126 /** 127 * Builds a health result. 128 * 129 * @return A new health result. 130 */ 131 public Health build() { 132 return new Health(this); 133 } 134 } 135}