@GetMapping(produces = {
        MediaType.APPLICATION_JSON_VALUE,
        MEDIA_TYPE_SPRING_BOOT_V2_JSON,
        MEDIA_TYPE_SPRING_BOOT_V3_JSON,
        MediaType.APPLICATION_FORM_URLENCODED_VALUE,
        MEDIA_TYPE_CAS_YAML
    })
    @Operation(summary = "Get SAML2 cached metadata for a SAML2 registered service. The service id could be the registered service numeric identifier, its name or actual service id. "
        + "In case the service definition points to an aggregate, you may also specify an entity id to locate the service provider within that aggregate",
        parameters = {
            @Parameter(in = ParameterIn.QUERY, name = "serviceId", required = true, description = "The service id"),
            @Parameter(in = ParameterIn.QUERY, name = "entityId", description = "The entity id"),
            @Parameter(in = ParameterIn.QUERY, name = "includeMetadata", description = "Whether to include the XML metadata in the response")
        })
    public ResponseEntity<? extends Map> getCachedMetadataObject(
        @RequestParam final String serviceId,
        @RequestParam(required = false, defaultValue = "true") final boolean includeMetadata,
        @Nullable
        @RequestParam(required = false) final String entityId,
        @RequestParam(required = false, defaultValue = "true") final boolean force) {

        val responseBody = new LinkedHashMap<String, Object>();
        val stopWatch = new StopWatch();
        stopWatch.start();
        try {
            return FunctionUtils.doAndHandle(() -> {
                val registeredService = findRegisteredService(serviceId);
                stopWatch.split();
                responseBody.put("registeredServiceSplitTime", stopWatch.formatSplitTime());

                val criteriaSet = new CriteriaSet();
                if (StringUtils.isNotBlank(entityId)) {
                    criteriaSet.add(new EntityIdCriterion(entityId));
                    criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
                } else {
                    criteriaSet.add(new EvaluableEntityRoleEntityDescriptorCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
                    criteriaSet.add(new SatisfyAnyCriterion(true));
                }
                val metadataResolverResult = force
                    ? Optional.of(cachingMetadataResolver.getObject().resolve(registeredService, criteriaSet))
                    : cachingMetadataResolver.getObject().getIfPresent(registeredService, criteriaSet);
                stopWatch.split();
                responseBody.put("metadataResolverSplitTime", stopWatch.formatSplitTime());

                val resultsMap = metadataResolverResult
                    .map(Unchecked.function(result -> {
                        val iteration = result.getMetadataResolver().resolve(criteriaSet).spliterator();
                        return StreamSupport.stream(iteration, false)
                            .filter(TimeBoundSAMLObject::isValid)
                            .map(entity -> {
                                val details = CollectionUtils.wrap("cachedInstant", result.getCachedInstant());
                                if (includeMetadata) {
                                    details.put("metadata", SamlUtils.transformSamlObject(openSamlConfigBean.getObject(), entity).toString());
                                }
                                return Pair.of(entity.getEntityID(), details);
                            })
                            .collect(Collectors.toMap(Pair::getLeft, Pair::getRight));
                    }))
                    .orElseThrow(() -> new SamlException("""
                    Unable to locate and resolve metadata for service %s. \
                    This can happen when the metadata entry is not found in the cache or \
                    the SAML2 service provider is unable to produce valid metadata via %s.
                    """.formatted(registeredService.getName(), registeredService.getMetadataLocation())));
                stopWatch.split();
                responseBody.put("metadataLoadSplitTime", stopWatch.formatSplitTime());
                responseBody.putAll(resultsMap);
                return ResponseEntity.ok(responseBody);
            }, e -> ResponseEntity.badRequest().body(Map.of("error", e.getMessage()))).get();
        } finally {
            stopWatch.stop();
        }
    }
Gets cached metadata object.

@param serviceId the service id
@param entityId  the entity id
@param force     the force
@return the cached metadata object
support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/metadata/SamlRegisteredServiceCachedMetadataEndpoint.java