How to declare a workspace?

Hi! Is it possible to write a migration that declares a workspace? I tried this like so, but the value integrator does take it:

{
    "topics": [
        {
            "value": "My Model",
            "uri": "my.testws",
            "TypeUri": "dmx.workspaces.workspace",
            "children": {
                "dmx.workspaces.workspace_name": {
                    "value": "My Model",
                    "uri": "my.testwsname",
                    "typeUri": "dmx.workspaces.workspace_name",
                },
                "dmx.workspaces.sharing_mode": {
                    "value": "Collaborative",
                    "uri": "dmx.workspaces.collaborative",
                    "typeUri": "dmx.workspaces.sharing_mode",
                }
            }
        }
    ]
}

Here is what is logged in the gogo shell: Caused by: java.lang.IllegalArgumentException: Tried to integrate values whose typeUri is not set.

Is there any information missing in my JSON snippet or isn’t it possible to create a workspace like this?

Caused by: java.lang.IllegalArgumentException: Tried to integrate values whose typeUri is not set

This happens because you have TypeUri instead typeUri (line 6).

Regarding Sharing Mode: you’re refering to the sharing mode by-value (“Collaborative”). The URI you state (dmx.workspaces.collaborative) is actually ignored by the ValueIntegrator, as it basically identifies things by-value. System resources (like Sharing Modes) however should be referred to by-URI instead:

{
    "topics": [
        {
            "uri": "my.testws",
            "typeUri": "dmx.workspaces.workspace",
            "children": {
                "dmx.workspaces.workspace_name": "My Model",
                "dmx.workspaces.sharing_mode": "ref_uri:dmx.workspaces.collaborative"
            }
        }
    ]
}

Note the ref_uri: value prefix. Use this to refer to existing values by-URI. (There is a ref_id: prefix as well.)

You don’t need to set the workspace value (“My Model”) as it is calculated automatically from Workspace Name (involving DMX’s general “Label Calculation” rules).

Note also the shortcut notation for children. In case your value don’t require an individual URI (usually only types require URIs) you can state the value directly, as a string (or whatever the value type is), instead of an object {value: "...", uri: "..."}).

That said, you can not create a workspace declaratively via a JSON migration. That workspace would have no owner (as well as no default topicmap), resulting in a corrupt DB. Instead you have to use the DMX Java API to create the workspace, and set the owner explicitly.

In contrast when you create a workspace interactively the current user (associated with the HTTP request) will become the workspace owner automatically. But when creating a workspace via migration, there is no “current user” (as there is no HTTP request in the 1st place).

Migrations are not triggered by any user, but by the system itself (in the moment an admin installs/updates a plugin).

Creating a workspace in a migration, using the dedicated DMX WorkspacesService and AccessControlService:

package your.plugin.migrations;

import systems.dmx.workspaces.WorkspacesService;
import systems.dmx.accesscontrol.AccessControlService;

import systems.dmx.core.Topic;
import systems.dmx.core.service.Inject;
import systems.dmx.core.service.Migration;
import systems.dmx.core.service.accesscontrol.SharingMode;

public class MigrationX extends Migration {

    @Inject
    private WorkspacesService ws;

    @Inject
    private AccessControlService acs;

    @Override
    public void run() {
        Topic workspace = ws.createWorkspace(
            "Your Workspace Name",
            "Your Workspace URI",
            SharingMode.COLLABORATIVE
        );
        acs.setWorkspaceOwner(workspace, "admin");
    }
}

Tell me if you need further help.

Thank you for the question!