Política ResponseCache

Estás consultando la documentación de Apigee Edge.
Consulta la documentación de Apigee X.
Información

Almacena en caché los datos de un recurso de backend, lo que reduce la cantidad de solicitudes que se le envían al recurso. Como las apps realizan solicitudes al mismo URI, puedes usar esta política para mostrar respuestas almacenadas en caché en lugar de reenviar esas solicitudes al servidor de backend. La política ResponseCache puede mejorar el rendimiento de la API mediante una latencia reducida y el tráfico de red.

Es probable que ResponseCache sea más útil cuando los datos de backend que usa tu API se actualizan solo de forma periódica. Por ejemplo, imagina que tienes una API que expone los datos del informe del clima actualizados solo cada diez minutos. Cuando usas ResponseCache para mostrar respuestas almacenadas en caché entre las actualizaciones, puedes reducir la cantidad de solicitudes que llegan al backend. Esto también reduce el número de saltos de red.

Para el almacenamiento en caché a corto plazo de uso general, considera usar la política de propagación de caché. Esa política se usa junto con la política de búsqueda de caché (para leer entradas de caché) y la política de invalidación de caché (para invalidar entradas).

Mira este video para obtener una introducción a la política ResponseCache.

Ejemplos

Caché de 10 minutos

En este ejemplo, se muestra cómo se conservan las respuestas en caché durante 10 minutos.

Imagina que tienes una API en la siguiente URL:

http://{org_name}-test.apigee.net/weather/forecastrss?w=23424778

Usas el parámetro de búsqueda w como clave de caché. Apigee Edge verifica el valor del parámetro de consulta w cada vez que se recibe una solicitud. Si una respuesta válida (es decir, no vencida) está presente en la caché, el mensaje de respuesta almacenado en caché se muestra al cliente que la solicita.

Ahora, supongamos que tienes una política ResponseCache configurada de la siguiente manera.

<ResponseCache name="ResponseCache">
    <CacheKey>
        <KeyFragment ref="request.queryparam.w" />
    </CacheKey>
    <ExpirySettings>
        <TimeoutInSeconds>600</TimeoutInSeconds>
    </ExpirySettings>
</ResponseCache>

La primera vez que el proxy de API recibe un mensaje de solicitud para la siguiente URL, la respuesta se almacena en caché. En la segunda solicitud, en un plazo de 10  minutos, se produce una búsqueda de caché; la respuesta se almacena en caché en la app sin que se reenvíe una solicitud al servicio de backend.

http://{org_name}-test.apigee.net/weather/forecastrss?w=23424778

Omite la búsqueda en caché

En el siguiente ejemplo, se muestra cómo omitir la búsqueda en caché y hacer que se actualice la caché. Consulta también este video sobre el uso de SkipCacheLookup.

La condición opcional SkipCacheLookup (si está configurada) se evalúa en la ruta de la solicitud. Si la condición se evalúa como verdadera, se omite la búsqueda de la caché y se actualiza la caché.

Un uso común de la actualización de la caché condicional es una condición que define un encabezado HTTP específico que hace que la condición se evalúe como verdadera. Se puede configurar una aplicación cliente con secuencia de comandos para enviar de forma periódica una solicitud con el encabezado HTTP adecuado, lo que genera que la caché de respuesta se actualice de forma explícita.

Por ejemplo, imagina una llamada a una API en la siguiente URL:

'http://{org_name}-test.apigee.net/weather/forecastrss?w=23424778' -H "bypass-cache:true"

Ahora, imaginemos que la siguiente política ResponseCache está configurada en ese proxy. Ten en cuenta que la condición bypass-cache se configura como verdadera.

<ResponseCache name="ResponseCache">
    <CacheKey>
        <KeyFragment ref="request.queryparam.w" />
    </CacheKey>
    <!-- Explicitly refresh the cached response -->
    <SkipCacheLookup>request.header.bypass-cache = "true"</SkipCacheLookup>
    <ExpirySettings>
        <TimeoutInSeconds>600</TimeoutInSeconds>
    </ExpirySettings>
</ResponseCache>

Para obtener más información sobre las condiciones, consulta Variables y condiciones de flujo.

Referencia del elemento

En la referencia del elemento, se describen los elementos y los atributos de la política.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseCache async="false" continueOnError="false" enabled="true" name="Response-Cache-1">
    <DisplayName>Response Cache 1</DisplayName>
    <Properties/>
    <CacheKey>
        <Prefix/>
        <KeyFragment ref="request.uri" />
    </CacheKey>
    <Scope>Exclusive</Scope>
    <ExpirySettings>
        <ExpiryDate/>
        <TimeOfDay/>
        <TimeoutInSeconds ref="flow.variable.here">300</TimeoutInSeconds>
    </ExpirySettings>
    <CacheResource>cache_to_use</CacheResource>
    <CacheLookupTimeoutInSeconds/>
    <ExcludeErrorResponse/>
    <SkipCacheLookup/>
    <SkipCachePopulation/>
    <UseAcceptHeader/>
    <UseResponseCacheHeaders/>
</ResponseCache>

Atributos <ResponseCache>

<ResponseCache async="false" continueOnError="false" enabled="true" name="Response-Cache-1">

En la siguiente tabla, se describen los atributos que son comunes a todos los elementos principales de las políticas:

Atributo Descripción Predeterminada Presencia
name

El nombre interno de la política. El valor del atributo name puede contener letras, números, espacios, guiones, guiones bajos y puntos. Este valor no puede superar los 255 caracteres.

De forma opcional, usa el elemento <DisplayName> para etiquetar la política en el editor de proxy de la IU de administración con un nombre de lenguaje natural diferente.

No disponible Obligatorias
continueOnError

Configúralo como false para mostrar un error cuando una política falla. Este es el comportamiento previsto para la mayoría de las políticas.

Configúralo como true para continuar con la ejecución del flujo incluso después de que una política falle.

false Opcional
enabled

Configúralo como true para aplicar la política.

Configúralo como false para desactivar la política. La política no se aplicará incluso si permanece adjunta a un flujo.

true Opcional
async

Este atributo dejó de estar disponible.

false Funciones obsoletas

Elemento <DisplayName>

Se usan además del atributo name para etiquetar la política en el editor de proxy de la IU de administración con un nombre de lenguaje natural diferente.

<DisplayName>Policy Display Name</DisplayName>
Predeterminada

No disponible

Si omites este elemento, se usa el valor del atributo name de la política.

Presencia Opcional
Tipo Cadena

Elemento <CacheKey>

Configura un puntero único para un dato almacenado en la caché.

Las claves de caché se limitan a un tamaño de 2 KB.

<CacheKey>
    <Prefix>string</Prefix>
    <KeyFragment ref="variable_name" />
    <KeyFragment>literal_string</KeyFragment>
</CacheKey>

Predeterminado:

No disponible

Presencia:

Obligatorio

Tipo:

No disponible

<CacheKey> construye el nombre de cada dato almacenado en la caché. A menudo, la clave se configura mediante un valor de los encabezados de entidad o los parámetros de búsqueda. En esos casos, el atributo ref del elemento especifica una variable que contiene el valor de la clave.

En el entorno de ejecución, los valores <KeyFragment> están precedidos del valor del elemento <Scope> o el valor <Prefix>. Por ejemplo, lo siguiente genera una clave de caché de UserToken__apiAccessToken__<value_of_client_id>:

<CacheKey>
    <Prefix>UserToken</Prefix>
    <KeyFragment>apiAccessToken</KeyFragment>
    <KeyFragment ref="request.queryparam.client_id" />
</CacheKey>

Debes usar el elemento <CacheKey> junto con <Prefix> y <Scope>. Para obtener más información, consulta Trabaja con claves de caché.

Elemento<CacheLookupTimeoutInSeconds>

Especifica la cantidad de segundos después de los cuales una búsqueda en caché incorrecta se considerará un error de caché. Si esto ocurre, el flujo se reanuda en la ruta de acceso del error de caché.

<CacheLookupTimeoutInSeconds>30</CacheLookupTimeoutInSeconds>

Predeterminado:

30

Presencia:

Opcional

Tipo:

Número entero

Elemento <CacheResource>

Especifica la caché en la que se deben almacenar los mensajes. Omite este elemento para usar la caché compartida que se incluye. Debes especificar un CacheResource por nombre si deseas poder borrar de manera administrativa las entradas contenidas en la caché. Para obtener más información, consulta Cachés.

<CacheResource>cache_to_use</CacheResource>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Para obtener más información sobre la configuración de cachés, consulta Crea y edita una caché de entorno.

Elemento <CacheKey>/<KeyFragment>

Especifica un valor que se debe incluir en la clave de caché lo que crea un espacio de nombres para hacer coincidir las solicitudes con las respuestas almacenadas en caché.

<KeyFragment ref="variable_name"/>
<KeyFragment>literal_string</KeyFragment>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

No disponible

Puede ser una clave (un nombre estático que proporcionas) o un valor (un conjunto de entradas dinámicas mediante la referencia de una variable). Todos los fragmentos especificados combinados (más el prefijo) se concatenan para crear la clave de caché.

<KeyFragment>apiAccessToken</KeyFragment>
<KeyFragment ref="request.queryparam.client_id" />

Debes usar el elemento <KeyFragment> junto con <Prefix> y <Scope>. Para obtener más información, consulta Trabaja con claves de caché.

Atributos

Atributo Tipo Predeterminado Obligatorio Descripción
ref cadena No

Variable de la que se obtiene el valor No debe usarse si este elemento contiene un valor literal.

Elemento <CacheKey>/<Prefix>

Especifica un valor para usar como prefijo de clave de caché.

<Prefix>prefix_string</Prefix>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Usa este valor en lugar de <Scope> cuando quieras especificar tu propio valor en lugar de un valor enumerado <Scope>. Si se define, <Prefix> antepone el valor de la clave de caché para las entradas escritas en la caché. Un valor de elemento <Prefix> anula un valor de elemento <Scope>.

Debes usar el elemento <Prefix> junto con <CacheKey> y <Scope>. Para obtener más información, consulta Trabaja con claves de caché.

Elemento <ExcludeErrorResponse>

En la actualidad, de forma predeterminada, esta política almacena en caché respuestas HTTP con cualquier código de estado posible. Esto significa que tanto las respuestas correctas como las de error se almacenan en caché. Por ejemplo, las respuestas con códigos de estado 2xx y 3xx se almacenan en caché de forma predeterminada.

Configura este elemento en true si no deseas almacenar en caché las respuestas de destino con códigos de estado de error HTTP. Solo se almacenarán en caché las respuestas con códigos de estado de 200 a 205 si este elemento es verdadero. Estos son los únicos códigos de estado HTTP que Edge registra como códigos de “éxito”, y no puedes cambiar esta asociación.

Para obtener más información sobre los patrones de caché de respuestas en los que este elemento es útil, consulta esta publicación de Comunidad.

Nota: En una actualización futura (a determinar), la configuración predeterminada de este elemento cambiará a “true”. Consulta las Notas de la versión de Apigee para obtener más información.

<ExcludeErrorResponse>true</ExcludeErrorResponse>

Predeterminado:

false

Presencia:

Opcional

Tipo:

Booleano

Elemento <ExpirySettings>

Especifica cuándo debe vencer una entrada de caché. Cuando está presente, <TimeoutInSeconds> anula <TimeOfDay> y <ExpiryDate>.

<ExpirySettings>
  <TimeOfDay ref="time_variable">expiration_time</TimeOfDay>
  <TimeoutInSeconds ref="duration_variable">seconds_until_expiration</TimeoutInSeconds>
  <ExpiryDate ref="date_variable">expiration_date</ExpiryDate>
</ExpirySettings>

Predeterminado:

No disponible

Presencia:

Obligatorio

Tipo:

No disponible

Elemento<ExpirySettings>/<ExpiryDate>

Especifica la fecha en la que debe vencer una entrada de caché. Usa el formato mm-dd-yyyy. Cuando está presente, el mismo nivel del elemento, <TimeoutInSeconds>, anula <ExpiryDate>.

<ExpirySettings>
    <ExpiryDate ref="{date_variable}">expiration_date</ExpiryDate>
</ExpirySettings>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Atributos

<ExpiryDate ref="" />
Atributo Descripción Predeterminado Presencia Tipo
ref

Variable de la que se obtiene el valor No debe usarse si este elemento contiene un valor literal.

No disponible Opcional String

Elemento <ExpirySettings>/<TimeOfDay>

La hora a la que debe vencer una entrada de caché. Usa el formato hh:mm:ss. Cuando está presente, el mismo nivel del elemento, <TimeoutInSeconds>, anula <TimeOfDay>.

Ingresa la hora del día con el formato HH:mm:ss, en el que HH representa la hora en un reloj de 24 horas. Por ejemplo, 14:30:00 por 2:30 en la tarde.

La hora, la configuración regional y la zona horaria predeterminadas, variarán según el lugar en que se ejecute el código (lo que no se sabe cuando se configura la política). Para obtener información sobre cómo configurar tu configuración regional, consulta Cómo crear y editar una caché de entorno.

<ExpirySettings>
    <TimeOfDay ref="time_variable">expiration_time</TimeOfDay>
</ExpirySettings>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Atributos

Atributo Descripción Predeterminado Presencia Tipo
ref Variable con el valor de tiempo de vencimiento No disponible Opcional Cadena

Elemento <ExpirySettings>/<TimeoutInSec>

Cantidad de segundos después de los cuales debe vencer una entrada de caché.

Elemento <ExpirySettings>/<TimeoutInSeconds>

Cantidad de segundos después de los cuales debe vencer una entrada de caché. Cuando está presente, este elemento anula los elementos de mismo nivel, <TimeOfDay> y <ExpiryDate>.

<ExpirySettings>
    <TimeoutInSeconds ref="duration_variable">seconds_until_expiration</TimeoutInSeconds>
</ExpirySettings>

Nota: Proporciona un valor predeterminado de tiempo de espera para usar si la referencia no recibe un valor de duration_variable.

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Atributos

Atributo Descripción Predeterminado Presencia Tipo
ref Variable con el valor de tiempo de espera.
No disponible
Opcional String

Elemento <Scope>

Enumeración que se usa a fin de construir un prefijo para una clave de caché cuando no se proporciona un elemento <Prefix> en el elemento <CacheKey>.

<Scope>scope_enumeration</Scope>

Predeterminado:

“Exclusivo”

Presencia:

Opcional

Tipo:

String

La configuración <Scope> determina una clave de caché que se antepone según el valor <Scope>. Por ejemplo, una clave de caché tomaría el siguiente formato cuando el alcance se configura como Exclusive: orgName__envName__apiProxyName__deployedRevisionNumber__proxy|TargetName__ [serializedCacheKey].

Si un elemento <Prefix> está presente en <CacheKey>, sustituye un valor de elemento <Scope>. Los valores válidos incluyen las enumeraciones a continuación.

Debes usar el elemento <Scope> junto con <CacheKey> y <Prefix>. Para obtener más información, consulta Trabaja con claves de caché.

Valores aceptables

Valor del permiso Descripción
Global

La clave de caché se comparte en todos los proxies de API implementados en el entorno. La clave de caché se antepone en el formato orgName __ envName __.

Si defines una entrada <CacheKey> con el apiAccessToken <KeyFragment> y un alcance <Global>, cada entrada se almacena como orgName__envName__apiAccessToken, seguida del valor serializado del token de acceso. Para un proxy de API implementado en un entorno llamado “test” en una organización llamada “apifactory”, los tokens de acceso se almacenarán en la siguiente clave de caché: apifactory__test__apiAccessToken.

Application

El nombre del proxy de la API se usa como prefijo.

La clave de caché se antepone en el formato orgName__envName__apiProxyName.

Proxy

La configuración de ProxyEndpoint se usa como prefijo.

La clave de caché se antepone en el formato orgName__envName__apiProxyName__deployedRevisionNumber__proxyEndpointName.

Target

La configuración TargetEndpoint se usa como prefijo.

La clave de caché se antepone en el formato orgName__envName__apiProxyName__deployedRevisionNumber__targetEndpointName.

Exclusive

predeterminada. Este es el más específico, por lo tanto, representa el riesgo mínimo de colisiones de espacio de nombres dentro de una caché determinada.

El prefijo es uno de estos dos formatos:

  • Si la política se adjunta al flujo ProxyEndpoint, el prefijo tiene el formato ApiProxyName_ProxyEndpointName.
  • Si se adjunta una política en TargetEndpoint, el prefijo tiene el formato ApiProxyName_TargetName.

La clave de caché se antepone en el formato orgName__envName__apiProxyName__deployedRevisionNumber__proxyNameITargetName

Por ejemplo, la string completa podría verse de la siguiente manera:

apifactory__test__weatherapi__16__default__apiAccessToken
.

Elemento<SkipCacheLookup>

Define una expresión que, si se evalúa como verdadera en el entorno de ejecución, especifica que la búsqueda en caché debe omitirse y la caché debe actualizarse. Consulta también este video sobre el uso de SkipCacheLookup.

<SkipCacheLookup>variable_condition_expression</SkipCacheLookup>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

En el siguiente ejemplo, si la variable bypass-cache se configura como verdadera en un encabezado entrante, la búsqueda en caché se omite y la caché se actualiza.

<SkipCacheLookup>request.header.bypass-cache = "true"</SkipCacheLookup>

Elemento<SkipCachePopulation>

Define una expresión que, si se evalúa como verdadera en el entorno de ejecución, especifica que se debe omitir una escritura en la caché. Consulta también este video sobre el uso de SkipCachePopulation.

<SkipCachePopulation>variable_condition_expression</SkipCachePopulation>

Predeterminado:

No disponible

Presencia:

Opcional

Tipo:

String

Por ejemplo, lo siguiente omitiría la escritura en caché si el código de estado de la respuesta fuera 400 o superior:

<SkipCachePopulation>response.status.code >= 400</SkipCachePopulation>

Elemento <UseAcceptHeader>

Configúralo como true para agregar la clave de caché de la entrada de caché a los valores de los encabezados de aceptación de respuesta.

Edge usa los encabezados de solicitud Accept, Accept-Encoding, Accept-Language y Accept-Charset cuando calcula la clave de caché. En este enfoque, se evita que un cliente obtenga un tipo de medio que no solicitó.

Por ejemplo, considera si dos solicitudes provienen de la misma URL, en la que la primera solicitud acepta gzip y la segunda no. La primera solicitud se almacenará en caché y es probable que la entrada en caché sea respuesta en formato gzip. La segunda solicitud leerá el valor almacenado en caché y, luego, podrá mostrar una entrada comprimida a un cliente que no puede leer en formato gzip.

Consulta Configura una clave de caché para obtener más información.

<UseAcceptHeader>false</UseAcceptHeader>

Predeterminado:

false

Presencia:

Opcional

Tipo:

Booleano

Elemento <UseResponseCacheHeaders>

Configúralo como true para que los encabezados de respuesta HTTP se consideren cuando se configure el “tiempo de actividad” (TTL) de la respuesta en la caché. Cuando esto es verdadero, Edge considera los valores de los siguientes encabezados de respuesta y compara los valores con los establecidos por <ExpirySettings> cuando configura el tiempo de actividad:

  • Cache-Control s-maxage
  • Cache-Control max-age
  • Expires

Consulta Configura el vencimiento de entradas de caché para obtener más detalles.

<UseResponseCacheHeaders>false</UseResponseCacheHeaders>

Predeterminado:

false

Presencia:

Opcional

Tipo:

Booleano

Notas de uso

El tamaño máximo de cada objeto almacenado en caché es de 256 KB. (Para obtener información detallada sobre cómo Edge procesa la caché, consulta Componentes internos de la caché).

Mediante la configuración de la política ResponseCache, puedes hacer que Edge incluya encabezados de respuesta HTTP en la configuración del vencimiento de la entrada de caché y de las claves de caché. En esta sección, se describe cómo puedes usar la política con encabezados para administrar el vencimiento y las claves de caché.

Para obtener más información sobre cómo Edge maneja los encabezados de respuesta con la política ResponseCache, consulta Compatibilidad con encabezados de respuesta HTTP.

Configura el tiempo de vencimiento de la entrada de caché

Al igual que con la política PopulateCache, puedes configurar el vencimiento de una entrada de caché de respuesta (su tiempo de actividad) con el elemento <ExpirySettings>. En la política ResponseCache, también puedes hacer que Edge considere los encabezados de respuesta cuando estén presentes.

Para usar encabezados de respuesta, debes configurar el valor del elemento <UseResponseCacheHeaders> como verdadero. Esa configuración hace que Edge considere los encabezados de respuesta, los compare con el valor establecido por <ExpirySettings> y, luego, use el valor más bajo entre ambos. Cuando se consideran los encabezados de respuesta, Edge elige el valor disponible como se describe a continuación:

Por ejemplo, imagina que una respuesta se almacena en caché con los siguientes valores:

  • Sin valor Cache-Control s-maxage
  • Un valor Cache-Control max-age de 300
  • Una fecha de Expires en tres días
  • Un valor <ExpirySettings> TimeoutInSeconds de 600.

En este caso, el valor Cache-Control max-age se usará para el TTL porque es menor que el valor <ExpirySettings> y porque no hay ningún valor Cache-Control s-maxage (que tiene prioridad sobre max-age).

Configura una clave de caché

Al igual que con las políticas de caché de uso general, como la política PopulateCache, con ResponseCache se usan elementos <CacheKey> y <Scope> a fin de configurar la creación de claves de caché para entradas de caché. Con ResponseCache, también puedes hacer que las claves de caché sean más significativas si incluyes encabezados de aceptación de respuestas adjuntos en los valores de las claves.

Si deseas obtener información para configurar claves de caché, consulta Trabaja con claves de caché. Si deseas obtener información sobre el uso de encabezados de aceptación, consulta <UseAcceptHeader>.

Información sobre la encriptación de caché

Edge para la nube pública: La caché está encriptada solo en organizaciones que tienen habilitada la HIPAA y PCI. La encriptación de esas organizaciones se configura durante el aprovisionamiento de estas.

Variables de flujo

Las siguientes variables predefinidas de flujo se propagan cuando se ejecuta una política de ResponseCache. Para obtener más información sobre las variables de flujo, consulta Referencia de las variables.

Variables Tipo Permisos Descripción
responsecache.{policy_name}.cachename String Solo lectura Muestra la caché usada en la política
responsecache.{policy_name}.cachekey String Solo lectura Muestra la clave usada
responsecache.{policy_name}.cachehit Booleano Solo lectura Verdadero si la ejecución de la política es adecuada
responsecache.{policy_name}.invalidentry Booleano Solo lectura Verdadero si la entrada de caché no es válida

Códigos de error

En esta sección, se describen los mensajes de error y las variables de flujo que se configuran cuando esta política activa un error. Esta información es importante si deseas saber si desarrollas reglas de fallas para un proxy. Para obtener más información, consulta Lo que necesitas saber sobre errores de políticas y Controla fallas.

Prefijo del código de error

No disponible

Errores de entorno de ejecución

Esta política no arroja ningún error de entorno de ejecución.

Errores en la implementación

Estos errores pueden generarse cuando implementas un proxy que contiene esta política.

Nombre del error Causa Corregir
InvalidTimeout Si el elemento <CacheLookupTimeoutInSeconds> de la política ResponseCache se establece en un número negativo, fallará la implementación del proxy de API.
InvalidCacheResourceReference Este error se produce si el elemento <CacheResource> de una política ResponseCache se establece con un nombre que no existe en el entorno en el que se implementa el proxy de la API.
ResponseCacheStepAttachmentNotAllowedReq Este error se produce si la misma política ResponseCache se adjunta a varias rutas de acceso de solicitud dentro de cualquier flujo de un proxy de API.
ResponseCacheStepAttachmentNotAllowedResp Este error se produce si la misma política ResponseCache se adjunta a varias rutas de respuesta dentro de cualquier flujo de un proxy de API.
InvalidMessagePatternForErrorCode Este error se produce si los elementos <SkipCacheLookup> o <SkipCachePopulation> de una política ResponseCache contienen una condición no válida.
CacheNotFound Este error se genera si la caché específica que se menciona en el mensaje de error no se creó en un componente específico del procesador de mensajes.

Variables con fallas

N/A

Ejemplo de respuesta de error

No disponible

Esquema

Un esquema XML (.xsd) define cada tipo de política. Como referencia, los esquemas de políticas están disponibles en GitHub.