> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/installation/kubernetes/kubernetes-upgrade/after-a-major-upgrade.md).

# After a major upgrade

What to put right once a major upgrade completes — Groovy scripts now live in the database, certification schedules were renamed, and customisations need reapplying.

## What this is

A major upgrade finishes with the platform running and several things still to put right. None of them stop the deployment from starting, which is why they are easy to miss — you find them later, when a synchronisation uses the wrong script or a campaign will not schedule.

Work through this page once the upgrade completes and before you hand the environment back. Everything here is database and configuration work, identical to the RPM procedure except where noted — the databases are the same regardless of how the platform is deployed.

{% hint style="danger" %}
**Every step here writes to the database.** Take the backup before you start, run each `SELECT` before its matching `UPDATE`, and check the row count is what you expect. These statements are not scoped to a single record.
{% endhint %}

## Groovy scripts now live in the database

This is the largest of the changes and the one most likely to break provisioning quietly.

Groovy scripts used to be referenced by file path. They are now registered in the `groovy.GROOVY_FILE` table and referenced by ID, and the references held elsewhere in the database still point at paths.

{% stepper %}
{% step %}

### Register any scripts of your own

Every custom script needs a row in `groovy.GROOVY_FILE` before anything can reference it. Scripts added for your own requirements will not be there — only the shipped ones are.
{% endstep %}

{% step %}

### See which properties still hold a path

Business rules, properties, batch tasks and synchronisation configurations can all carry a Groovy reference. Start with the properties, and look before you write:

{% code overflow="wrap" %}

```sql
SELECT p.PROPERTY_ID, p.PROPERTY_VALUE AS OLD_VALUE, g.GROOVY_SCRIPT_ID AS NEW_VALUE, p.CATEGORY
FROM openiam.PROPERTY_FILE_VALUES p
JOIN groovy.GROOVY_FILE g
  ON g.FILE_NAME = REPLACE(SUBSTRING_INDEX(p.PROPERTY_VALUE, '/', -1), '.groovy', '')
WHERE p.PROPERTY_TYPE = 'GROOVY'
  AND p.PROPERTY_VALUE LIKE '%/%'
ORDER BY p.CATEGORY, p.PROPERTY_ID;
```

{% endcode %}

{% hint style="warning" %}
**The join has to match on path as well as filename**, or two scripts of the same name in different folders will resolve to whichever the database returns first. The full form, including the path comparison, is in the source procedure — check it against your own folder layout before running the update.
{% endhint %}
{% endstep %}

{% step %}

### Replace the paths with IDs

Once the `SELECT` returns what you expect, and only then, update the same rows to store `GROOVY_SCRIPT_ID` in place of the path. Repeat for the other tables that carry a `GroovyScriptURL`.
{% endstep %}

{% step %}

### Confirm nothing is left

Re-run the `SELECT`. It should return no rows. Then exercise a synchronisation, a reconciliation and a provisioning operation — the reference is only proven by something using it.
{% endstep %}
{% endstepper %}

### Check the connector response handler

An IDM error about a missing connector response handler script means this property did not survive:

{% code overflow="wrap" %}

```sql
SELECT * FROM PROPERTY_FILE_VALUES
WHERE PROPERTY_ID = 'org.openiam.idm.connector.response.handler.script';
```

{% endcode %}

A row means it is configured. No row means it must be added — find the id with `SELECT * FROM GROOVY_FILE WHERE FILE_NAME LIKE 'CustomConnectorResponse%'` in the `groovy` schema, then insert the property with `PROPERTY_TYPE = 'Groovy'` and that id as its value.

**Check the others at the same time.** Many defaults are now defined through the properties table, not just this one. Either walk the tabs under **Administration → System configuration** in the Webconsole, or count them:

{% code overflow="wrap" %}

```sql
SELECT COUNT(*) FROM PROPERTY_FILE_VALUES WHERE PROPERTY_TYPE = 'Groovy';
```

{% endcode %}

## Certification schedule types were renamed

Deprecated schedule values remain in the data after the upgrade and must be normalised, or the affected certifications will not schedule.

{% code overflow="wrap" %}

```sql
SELECT id, name, schedule_type FROM access_certification WHERE schedule_type IS NOT NULL;
```

{% endcode %}

| Old value         | New value       |
| ----------------- | --------------- |
| `INTERVAL_2`      | `SEMI_ANNUALLY` |
| `INTERVAL_4`      | `QUARTERLY`     |
| `INTERVAL_ANNUAL` | `ANNUALLY`      |

Update each inside a transaction, one value at a time:

{% code overflow="wrap" %}

```sql
BEGIN;
UPDATE access_certification SET schedule_type = 'SEMI_ANNUALLY' WHERE schedule_type = 'INTERVAL_2';
COMMIT;
```

{% endcode %}

## Review your Groovy scripts against the new connector responses

Connector error handling changed, so scripts that parse responses may need adjusting — improved error parsing and logging, and different return values or exception handling.

Check every one of these categories:

* Policy map scripts
* Pre-processor and post-processor scripts
* `ConnectorResponse` scripts, and all connector scripts
* Transformation and validation scripts
* `DefaultProvisionServiceEventProcessor.groovy`
* `TestScriptConnector.groovy`
* `CustomNotificationDelegate.groovy`
* All batch scripts

## Reapply what the upgrade did not carry over

**Custom styling.** A theme stylesheet is an override placed under `/data/openiam/conf/ui/static/custom/` — the same path as RPM, here backed by the `openiam-pvc-storage-ui-custom-static` persistent volume claim rather than host storage. Put `custom.css` back, check the file permissions, and restart the `ui-static` StatefulSet:

{% code overflow="wrap" %}

```bash
kubectl rollout restart statefulset/ui-static
```

{% endcode %}

{% hint style="info" %}
**Confirm the resource name first** — `kubectl get statefulsets` — since a Helm release name can prefix it. [*Brand the portals*](/getting-started-guide/brand-the-portals.md) covers the rest of the styling procedure, but is written for RPM; the file path and the restart step above are what differ on Kubernetes.
{% endhint %}

**Content patterns.** Re-add the default content pattern used before the upgrade, so existing templates and pages keep resolving.

**The template-based user page.** Confirm it is enabled and visible in the UI.

## Known issue — Managed System attributes look blank

An attribute value can appear blank after being entered. Press **Enter** after typing it, then **Save** — the value is registered on Enter, and saving without it discards the entry.

## Before you hand it back

* Groovy references resolve to ids, and no path-based reference remains
* The connector response handler property exists, and the other Groovy properties with it
* Certification schedule types carry no deprecated values
* Custom scripts reviewed against the new connector response handling
* Custom styles restored and serving
* Legacy content patterns reintroduced
* A synchronisation, a reconciliation and a provisioning operation each run cleanly

## Related

* [Major upgrade](/installation/kubernetes/kubernetes-upgrade/major-upgrade.md) — the upgrade this follows
* [Release-specific steps](/installation/kubernetes/kubernetes-upgrade/release-specific-steps.md) — databases and services added by particular releases
* [After a major upgrade — RPM](/installation/rpm/rpm-upgrade/after-a-major-upgrade.md) — the same page this was copied from
* [Brand the portals](/getting-started-guide/brand-the-portals.md) — where custom styling lives, written for RPM

*Last reviewed 9 September 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/installation/kubernetes/kubernetes-upgrade/after-a-major-upgrade.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
