I already covered out-of-place patching from the web UI, but patching tasks should be automated, and clicking through the same screens for every deployment can get repetitive. Let’s do the exact same out-of-place patch of a GoldenGate Microservices Architecture deployment, this time entirely with the REST API.

Every step below shows two ways to make the same call:

  • A standard requests call, the default Python module to handle REST APIs.
  • The equivalent call using oggrestapi.py, the OGGRestAPI Python client I presented in another blog, which handles everything for you.

Installing the latest version of GoldenGate

This part does not change: the REST API cannot install software on the server, so you still need to unzip the patched installation to a new OGG_HOME and run runInstaller in silent mode, as described in the web UI blog.

Patching the Service Manager with the REST API

As with the web UI, the Service Manager has to be patched first. Assume the following setup:

  • sm_url: https://vmogg:7809
  • new_ogg_home: /u01/app/ogg/product/23.26.2.0.1
  • username / password: an administrator on the Service Manager

Updating OGG_HOME is a PATCH call on the ServiceManager deployment:

import requests

sm_url = "https://vmogg:7809"
auth = ("oggadmin", "password")

requests.patch(
    f"{sm_url}/services/v2/deployments/ServiceManager",
    json={"oggHome": "/u01/app/ogg/product/23.26.2.0.1"},
    auth=auth,
)

With oggrestapi.py:

from oggrestapi import OGGRestAPI

client = OGGRestAPI(url="https://vmogg:7809", username="oggadmin", password="password")
client.update_deployment(deployment="ServiceManager", ogg_home="/u01/app/ogg/product/23.26.2.0.1")

Already, you can see that the REST API client simplifies the patching a lot.

Restarting the Service Manager is the same endpoint, this time setting status:

requests.patch(
    f"{sm_url}/services/v2/deployments/ServiceManager",
    json={"status": "restart"},
    auth=auth,
)
client.restart_deployment(deployment="ServiceManager")

restart_deployment is a dedicated method in oggrestapi.py, following the same pattern already used for restart_service, restart_extract and restart_replicat. It makes it easier to use the API, instead of building the {"status": "restart"} payload yourself. It also takes an optional only_if_running argument, so a deployment that was already stopped before the patch is left alone rather than being started by the restart call.

As with the web UI, all your deployment processes are still running on the old OGG_HOME at this point. The AIService, introduced in 26ai, does not pick up the new home automatically either. You should then list the services attached to the Service Manager and restart the ones that are not ServiceManager itself:

services = requests.get(
    f"{sm_url}/services/v2/deployments/ServiceManager/services",
    auth=auth,
).json()["response"]["items"]

for service in services:
    if service["name"] != "ServiceManager":
        requests.patch(
            f"{sm_url}/services/v2/deployments/ServiceManager/services/{service['name']}",
            json={"status": "restart"},
            auth=auth,
        )
for service in client.list_services("ServiceManager"):
    if service.get("name") != "ServiceManager":
        client.restart_service(deployment="ServiceManager", service=service.get("name"))

Patching each deployment with the REST API

Once the Service Manager runs on the new home, repeat the same update, then restart sequence for each deployment (oggHome, then status: restart):

deployment = "ogg_test_01"

requests.patch(
    f"{sm_url}/services/v2/deployments/{deployment}",
    json={"oggHome": "/u01/app/ogg/product/23.26.2.0.1"},
    auth=auth,
)

requests.patch(
    f"{sm_url}/services/v2/deployments/{deployment}",
    json={"status": "restart"},
    auth=auth,
)
client.update_deployment(deployment="ogg_test_01", ogg_home="/u01/app/ogg/product/23.26.2.0.1")
client.restart_deployment(deployment="ogg_test_01")

Once the deployment is back up, restart its extracts and replicats. Since these processes are not accessible through the Service Manager port, you need to change the URL. If you use a reverse proxy setup, or auto_discovery=True (see below), this is also easier with the Python client.

admin_url = "https://vmogg:7810"

extracts = requests.get(f"{admin_url}/services/v2/extracts", auth=auth).json()["response"]["items"]
for extract in extracts:
    requests.patch(f"{admin_url}/services/v2/extracts/{extract['name']}", json={"status": "stopped"}, auth=auth)
    requests.patch(f"{admin_url}/services/v2/extracts/{extract['name']}", json={"status": "running"}, auth=auth)

replicats = requests.get(f"{admin_url}/services/v2/replicats", auth=auth).json()["response"]["items"]
for replicat in replicats:
    requests.patch(f"{admin_url}/services/v2/replicats/{replicat['name']}", json={"status": "stopped"}, auth=auth)
    requests.patch(f"{admin_url}/services/v2/replicats/{replicat['name']}", json={"status": "running"}, auth=auth)

With oggrestapi.py, restart_all_extracts and restart_all_replicats do the same thing on an OGGRestAPI client already pointed at the deployment (either connected directly to its Administration Service, or through an NGINX reverse proxy with deployment= set):

admin_client = OGGRestAPI(url="https://vmogg:7810", username="oggadmin", password="password")
admin_client.restart_all_extracts(only_if_running=True)
admin_client.restart_all_replicats(only_if_running=True)

Automating the whole patching in one call

The steps listed above (update home, restart deployment, restart processes for every deployment) is exactly what patch_deployment (a single deployment) and patch_deployments (all of them) already do in oggrestapi.py, internally calling restart_deployment for the restart step. They also handle the ServiceManager special case (patch and restart the deployment and its services, but never restart extracts and replicats on it) and the wait_until_deployment_status polling in between:

client = OGGRestAPI(url="https://vmogg:7809", username="oggadmin", password="password", reverse_proxy=True)
client.patch_deployments(new_home="/u01/app/ogg/product/23.26.2.0.1", ask_credentials=False)

Both methods take restart_after_patch and restart_processes_after_patch (both default to True) if you need to skip either step, for example to patch every home first and restart everything in a separate maintenance window:

client.patch_deployments(
    new_home="/u01/app/ogg/product/23.26.2.0.1",
    restart_after_patch=False,
    restart_processes_after_patch=False,
    ask_credentials=False,
)

restart_processes_after_patch=True needs per-deployment routing: restarting extracts and replicats on ogg_test_01 is a different call than on ogg_test_02, and a plain connection to the Service Manager’s own port has no way to reach either one. oggrestapi.py gives you two ways to get that routing from a single client:

  • reverse_proxy=True, shown above, if you already run NGINX in front of your deployments.
  • auto_discovery=True, with no reverse proxy at all. The client looks up each deployment’s real Administration/Distribution/Performance Metrics Service port through the Service Manager itself (the same GET .../deployments/{deployment}/services/{service} call), the first time each one is actually needed, and reuses that lookup for the rest of the run:
client = OGGRestAPI(url="https://vmogg:7809", username="oggadmin", password="password", auto_discovery=True)
client.patch_deployments(new_home="/u01/app/ogg/product/23.26.2.0.1", ask_credentials=False)

Without either flag, patch with restart_processes_after_patch=False and restart each deployment’s processes yourself through a separate client pointed at that deployment’s own admin URL.

Some services are still running on the old OGG_HOME

Same as with the web UI: a restart call on a deployment returns as soon as the Administration Service (adminsrvr) is back up. The Receiver Service (recvsrvr) or the Distribution Service (distsrvr) can take a bit longer to restart. If, after polling for a few minutes, a service is still reporting the old home, restart it individually with the same PATCH .../services/{service} call shown above for the AIService, or with the restart_service method.

Other things to consider

If you change the name of your home at every release, remember to update OGG_HOME in every script and environment that references it, for example:

  • DMK environment files.
  • systemd service files, which might hardcode the OGG_HOME variable.