You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/07/14 10:16:32 UTC
[brooklyn-server] 01/05: add failing test for import not allowing bundles in unusual orders
This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 840f6f8b840faebbd702663a162828a4601a7b78
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Wed Jul 13 12:02:31 2022 +0100
add failing test for import not allowing bundles in unusual orders
---
.../catalog/internal/BasicBrooklynCatalog.java | 5 +-
.../apache/brooklyn/core/mgmt/ha/OsgiManager.java | 11 ++-
.../BrooklynBomYamlCatalogBundleResolver.java | 3 +-
.../brooklyn/rest/resources/ServerResource.java | 1 +
.../rest/resources/ApplicationResourceTest.java | 10 +--
.../rest/resources/ServerResourceTest.java | 96 +++++++++++++++++++++-
6 files changed, 116 insertions(+), 10 deletions(-)
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index ce10b25a80..8e742eb6cf 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -1607,8 +1607,9 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
itemSpecInstantiated = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true);
if (!candidateYaml.contains("services:")) {
- // 'services:' blueprints still need legacy plan-to-spec converter
- log.warn("Instantiation of this blueprint was only possible with legacy plan-to-spec converter, will likely not be supported in future versions:\n" + candidateYaml);
+ // 'services:' blueprints still need legacy plan-to-spec converter, don't even debug on that.
+ // for others
+ log.debug("Instantiation of this blueprint was only possible with legacy plan-to-spec converter, may not be supported in future versions:\n" + candidateYaml);
}
}
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 65b81e5ada..edd4349396 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -440,7 +440,7 @@ public class OsgiManager {
@Nullable ManagedBundle knownBundleMetadata, @Nullable Supplier<InputStream> zipIn, boolean validateTypes) {
BundleInstallationOptions options = new BundleInstallationOptions();
options.setDeferredStart(true);
- options.setFormat(knownBundleMetadata.getFormat());
+ if (knownBundleMetadata!=null) options.setFormat(knownBundleMetadata.getFormat());
options.setValidateTypes(validateTypes);
options.setKnownBundleMetadata(knownBundleMetadata);
return BrooklynCatalogBundleResolvers.install(getManagementContext(), zipIn, options);
@@ -464,11 +464,20 @@ public class OsgiManager {
public ReferenceWithError<OsgiBundleInstallationResult> installBrooklynBomBundle(
@Nullable ManagedBundle knownBundleMetadata, Supplier<InputStream> input,
boolean start, boolean loadCatalogBom, boolean forceUpdateOfNonSnapshots) {
+ return installBrooklynBomBundle(knownBundleMetadata, input, start, loadCatalogBom, forceUpdateOfNonSnapshots, true, false);
+ }
+
+ @Beta
+ public ReferenceWithError<OsgiBundleInstallationResult> installBrooklynBomBundle(
+ @Nullable ManagedBundle knownBundleMetadata, Supplier<InputStream> input,
+ boolean start, boolean loadCatalogBom, boolean forceUpdateOfNonSnapshots, boolean validate, boolean deferredStart) {
BundleInstallationOptions options = new BundleInstallationOptions();
options.setKnownBundleMetadata(knownBundleMetadata);
options.setStart(start);
options.setLoadCatalogBom(loadCatalogBom);
options.setForceUpdateOfNonSnapshots(forceUpdateOfNonSnapshots);
+ options.setValidateTypes(validate);
+ options.setDeferredStart(deferredStart);
return BrooklynCatalogBundleResolvers.install(getManagementContext(), input, options);
}
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java
index 72ae2dc361..f4ed4b02aa 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java
@@ -134,7 +134,8 @@ public class BrooklynBomYamlCatalogBundleResolver extends AbstractCatalogBundleR
basicManagedBundle.tags().addTags((Iterable<?>)cm.get("tags"));
}
result = ((ManagementContextInternal)mgmt).getOsgiManager().get().installBrooklynBomBundle(
- basicManagedBundle, InputStreamSource.of("ZIP generated for "+vn+": "+bf, bf), options.isStart(), options.isLoadCatalogBom(), options.isForceUpdateOfNonSnapshots()).get();
+ basicManagedBundle, InputStreamSource.of("ZIP generated for "+vn+": "+bf, bf), options.isStart(), options.isLoadCatalogBom(), options.isForceUpdateOfNonSnapshots(),
+ options.isValidateTypes(), options.isDeferredStart()).get();
} finally {
bf.delete();
}
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
index 0c7739a404..812ede244d 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
@@ -661,6 +661,7 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv
} catch (Exception e){
Exceptions.propagateIfFatal(e);
ApiError.Builder error = ApiError.builder().errorCode(Response.Status.BAD_REQUEST);
+ log.warn("Error importing persisted state: "+e, e);
error.message(e.getMessage());
return error.build().asJsonResponse();
} finally {
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
index 701a09194b..1882fdf42e 100644
--- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
@@ -213,7 +213,7 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
.build();
Response response = clientDeploy(spec);
- assertTrue(response.getStatus() / 100 == 2, "response is " + response);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
// Expect app to be running
URI appUri = response.getLocation();
@@ -227,7 +227,7 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
Response response = client().path("/applications")
.post(Entity.entity(yaml, "application/x-yaml"));
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
// Expect app to be running
URI appUri = response.getLocation();
@@ -250,7 +250,7 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
" static.value: " + SENSOR_TEXT_VALUE);
Response response = client().path("/applications")
.post(Entity.entity(yaml, "application/x-yaml"));
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
// Fetch applications, find 'simple-app-yaml-with-invalid-sensor-type' application and inspect details.
Collection apps = client().path("/applications/fetch").get(Collection.class);
@@ -275,7 +275,7 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
Response response = client().path("/applications")
.header(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA)
.post(body);
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
// Expect app to be running
URI appUri = response.getLocation();
@@ -297,7 +297,7 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
Response response = client().path("/applications")
.post(Entity.entity(yaml, "application/x-yaml"));
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
// Expect app to be running
URI appUri = response.getLocation();
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceTest.java
index 786f8dbfd4..d08dad477d 100644
--- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceTest.java
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -30,6 +31,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.brooklyn.api.entity.EntitySpec;
@@ -37,10 +40,18 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
import org.apache.brooklyn.core.BrooklynVersion;
+import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.core.typereg.BrooklynBomYamlCatalogBundleResolver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
@@ -49,8 +60,15 @@ import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.rest.domain.HighAvailabilitySummary;
import org.apache.brooklyn.rest.domain.VersionSummary;
import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
+import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Suppliers;
+import org.apache.brooklyn.util.http.HttpAsserts;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.Duration;
import org.apache.cxf.jaxrs.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,7 +83,10 @@ import com.google.common.collect.Iterables;
public class ServerResourceTest extends BrooklynRestResourceTest {
private static final Logger log = LoggerFactory.getLogger(ServerResourceTest.class);
-
+
+ @Override
+ protected boolean useOsgi() { return true; }
+
@Test
public void testGetVersion() throws Exception {
VersionSummary version = client().path("/server/version").get(VersionSummary.class);
@@ -93,6 +114,79 @@ public class ServerResourceTest extends BrooklynRestResourceTest {
List<String> entryNames = listEntryNames(zip);
assertTrue(Iterables.tryFind(entryNames, StringPredicates.containsLiteral(app.getId())).isPresent(), "entries="+entryNames);
assertTrue(Iterables.tryFind(entryNames, StringPredicates.containsLiteral(loc.getId())).isPresent(), "entries="+entryNames);
+
+ Entities.unmanage(app);
+ }
+
+ @Test
+ public void testExportPersistedStateWithBundlesThenReimport() throws Exception {
+ // export seems to preserve install order probably to minimise conflicts, so use deferred start to get the problematic order
+ OsgiBundleInstallationResult r2 = ((ManagementContextInternal) manager).getOsgiManager().get().installDeferredStart(null,
+ () -> new ByteArrayInputStream(Strings.lines(
+ "brooklyn.catalog:",
+ " bundle: b2",
+ " version: 1",
+ " id: b2",
+ " itemType: entity",
+ " item:",
+ " type: b1"
+ ).getBytes()),
+ false).get();
+
+ ((ManagementContextInternal) manager).getOsgiManager().get().install(
+ () -> new ByteArrayInputStream(Strings.lines(
+ "brooklyn.catalog:",
+ " bundle: b1",
+ " version: 1",
+ " id: b1",
+ " itemType: entity",
+ " item:",
+ " type: org.apache.brooklyn.core.test.entity.TestEntity"
+ ).getBytes()),
+ BrooklynBomYamlCatalogBundleResolver.FORMAT, false, null).get();
+
+ r2.getDeferredStart().run();
+
+ String yaml = "services: [ { type: b2 } ]";
+ Response response = client().path("/applications")
+ .post(Entity.entity(yaml, "application/x-yaml"));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+
+ org.apache.brooklyn.api.entity.Entity b2 = Iterables.getOnlyElement(Iterables.getOnlyElement(manager.getApplications()).getChildren());
+ Asserts.assertInstanceOf(b2, TestEntity.class);
+
+ byte[] zip = client().path("/server/ha/persist/export").get(byte[].class);
+
+ // restart the server, so it has nothing, then try importing
+ destroyClass();
+
+ File mementoDir = Os.newTempDir(getClass());
+ manager = RebindTestUtils.managementContextBuilder(mementoDir, getClass().getClassLoader())
+ .persistPeriodMillis(Duration.ONE_MINUTE.toMilliseconds())
+ .haMode(HighAvailabilityMode.MASTER)
+ .forLive(true)
+ .enablePersistenceBackups(false)
+ .emptyCatalog(true)
+// .properties(false)
+ .setOsgiEnablementAndReuse(useOsgi(), true)
+ .buildStarted();
+ new BrooklynCampPlatformLauncherNoServer()
+ .useManagementContext(manager)
+ .launch();
+
+ initClass();
+
+ Asserts.assertNull(manager.getTypeRegistry().get("b2"));
+ Asserts.assertSize(manager.getApplications(), 0);
+
+ Response importResponse = client().path("/server/ha/persist/import").post(Entity.entity(zip, MediaType.APPLICATION_OCTET_STREAM_TYPE));
+ HttpAsserts.assertHealthyStatusCode(importResponse.getStatus());
+
+ Asserts.assertNotNull(manager.getTypeRegistry().get("b1"));
+ Asserts.assertNotNull(manager.getTypeRegistry().get("b2"));
+ org.apache.brooklyn.api.entity.Entity b2b = Iterables.getOnlyElement(Iterables.getOnlyElement(manager.getApplications()).getChildren());
+ Asserts.assertInstanceOf(b2b, TestEntity.class);
+ Asserts.assertEquals(b2b.getId(), b2.getId());
}
private List<String> listEntryNames(byte[] zip) throws Exception {