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.microservice.management;
018
019import java.util.*;
020
021import org.apache.juneau.commons.runtime.*;
022import org.apache.juneau.marshall.collections.*;
023import org.apache.juneau.rest.server.*;
024
025/**
026 * Shared worker for the {@code /info} management endpoint:  renders the running application's
027 * {@link ManifestFile} main attributes (build/version/git metadata) as a map.
028 *
029 * <p>
030 * Both the {@link InfoMixin mixin} and {@link InfoResource resource} flavors delegate here, so the two
031 * forms cannot drift &mdash; the same shared-worker pattern the health and metrics surfaces use.
032 *
033 * <p>
034 * The manifest is resolved from the host bean store.  A standalone microservice registers its
035 * {@link ManifestFile} bean during {@code Microservice.init()}, so the {@code Main-*} attributes (and any
036 * build-side stamped {@code Build-*}/{@code Git-*} fields) are reachable here.  When no manifest bean is
037 * present the endpoint degrades cleanly to an empty map rather than failing.
038 *
039 * <h5 class='section'>See Also:</h5><ul>
040 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ManagementSurface">Management Surface (Actuator-style endpoints)</a>
041 * </ul>
042 *
043 * @since 10.0.0
044 */
045public class InfoManager {
046
047   /**
048    * Resolves the application's {@link ManifestFile} from the host context's bean store.
049    *
050    * @param context The REST context whose bean store is searched.  May be <jk>null</jk>.
051    * @return The manifest, or <jk>null</jk> if none is registered (or the context is <jk>null</jk>).
052    */
053   @SuppressWarnings({
054      "resource" // The bean store is owned by the RestContext; this adapter only borrows beans and must not close it.
055   })
056   public ManifestFile resolveManifest(RestContext context) {
057      if (context == null)
058         return null;
059      return context.getBeanStore().getBean(ManifestFile.class).orElse(null);
060   }
061
062   /**
063    * Renders the manifest's main attributes (build/version/git metadata) as a sorted map.
064    *
065    * @param manifest The resolved manifest, or <jk>null</jk> (in which case an empty map is returned).
066    * @return A sorted map of manifest attribute &rarr; value (empty when {@code manifest} is <jk>null</jk>); never <jk>null</jk>.
067    */
068   public JsonMap getInfo(ManifestFile manifest) {
069      var out = new JsonMap();
070      if (manifest != null)
071         out.putAll(new TreeMap<>(manifest.asMap()));
072      return out;
073   }
074}