diff --git a/doc/guide.md b/doc/guide.md index 4d46c9630..fb83851d0 100644 --- a/doc/guide.md +++ b/doc/guide.md @@ -1100,6 +1100,11 @@ posted. Note that Okapi gives us less details about the modules, for in the real life this could be quite a long list. +Modules are immutable (for same id). There is no PUT method to update a module. +It is possible to POST the module descriptor again, if it is equivalent to the +existing module. This enforcement can be lifted, by supplying query +parameter `check=false`. + #### Deploying the module It is not enough that Okapi knows that such a module exists. We must diff --git a/okapi-core/src/main/java/org/folio/okapi/managers/ModuleManager.java b/okapi-core/src/main/java/org/folio/okapi/managers/ModuleManager.java index 757e6243c..f37870b38 100644 --- a/okapi-core/src/main/java/org/folio/okapi/managers/ModuleManager.java +++ b/okapi-core/src/main/java/org/folio/okapi/managers/ModuleManager.java @@ -78,7 +78,7 @@ private Future loadModules() { * Create a list of modules. * * @param list list of modules - * @param check whether to check dependencies + * @param check whether to check dependencies and immutability of existing modules * @param removeIfMissingDep skip modules where dependency check fails * @return future */ @@ -91,7 +91,7 @@ public Future createList(List list, boolean check, * Create a list of modules. * * @param list list of modules - * @param check whether to check dependencies + * @param check whether to check dependencies and immutability of existing modules * @param moduleVersionFilter whether to allow pre-release/npmSnapshots * @param removeIfMissingDep skip modules where dependency check fails * @return future @@ -110,7 +110,7 @@ public Future createList(List list, boolean check, ModuleDescriptor exMd = tempList.get(id); String exJson = Json.encodePrettily(exMd); String json = Json.encodePrettily(md); - if (!json.equals(exJson)) { + if (check && !json.equals(exJson)) { return Future.failedFuture(new OkapiError(ErrorType.USER, messages.getMessage("10203", id))); } diff --git a/okapi-core/src/main/raml/okapi.raml b/okapi-core/src/main/raml/okapi.raml index 4afa97767..089759ba5 100644 --- a/okapi-core/src/main/raml/okapi.raml +++ b/okapi-core/src/main/raml/okapi.raml @@ -453,7 +453,10 @@ traits: /_/proxy/modules. queryParameters: check: - description: Whether to check dependencies + description: Whether to check dependencies and immutability of existing modules. + If false, modules may be imported requiring interfaces that are not currently + offered by any other module. Also with a false value an existing module may be + updated; thus breaking immutability. type: boolean required: false default: true @@ -530,7 +533,10 @@ traits: selected for a specific tenant. queryParameters: check: - description: Whether to check dependencies + description: Whether to check dependencies and immutability of existing modules. + If false, a module may be imported requiring interfaces that are not currently + offered by any other module. Also with a false value an existing module may + be updated; thus breaking immutability. type: boolean required: false default: true diff --git a/okapi-core/src/test/java/org/folio/okapi/ModuleTest.java b/okapi-core/src/test/java/org/folio/okapi/ModuleTest.java index 08969a767..6c3342219 100644 --- a/okapi-core/src/test/java/org/folio/okapi/ModuleTest.java +++ b/okapi-core/src/test/java/org/folio/okapi/ModuleTest.java @@ -948,6 +948,17 @@ public void testOneModule(TestContext context) { .body(equalTo("create: module sample-module-1+1 already exists")); assertEmptyReport(c); + // post it again with slight modification, but check=false, so it should be allowed, and replace the old one + c = api.createRestAssured3(); + c.given() + .header("Content-Type", "application/json") + .body(docSampleModule.replace("sample.extra\"", "sample.foo\"")) + .queryParam("check", "false") + .post("/_/proxy/modules") + .then() + .statusCode(201); + assertEmptyReport(c); + given() .header("Content-Type", "application/json") .body("{}")