/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.brooklyn.entity.brooklynnode;
import java.net.URI;
import java.util.concurrent.Callable;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.HttpTestUtils;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.http.HttpTool;
import org.apache.brooklyn.util.http.HttpToolResponse;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.repeat.Repeater;
import org.apache.brooklyn.util.time.Duration;
import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.launcher.SimpleYamlLauncherForTests;
import org.apache.brooklyn.launcher.camp.SimpleYamlLauncher;
import com.google.common.collect.Iterables;
/** REST-accessible extension of {@link BrooklynNodeTest} */
public class BrooklynNodeRestTest {
private static final Logger log = LoggerFactory.getLogger(BrooklynNodeRestTest.class);
// takes a while when run on its own, because initializing war and making some requests;
// but there are no waits (beyond 10ms), the delay is all classloading;
// and this tests a lot of things, REST API, Brooklyn Node, yaml deployment,
// so feels worth it to have as a unit test
// FIXME[BROOKLYN-43]: Test fails if security is configured in brooklyn.properties.
@Test(groups = "WIP")
public void testBrooklynNodeRestDeployAndMirror() {
final SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
try {
TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class, l.getManagementContext());
BrooklynNode bn = app.createAndManageChild(EntitySpec.create(BrooklynNode.class, SameBrooklynNodeImpl.class));
bn.start(MutableSet.<Location>of());
URI uri = bn.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
Assert.assertNotNull(uri);
EntityTestUtils.assertAttributeEqualsEventually(bn, Attributes.SERVICE_UP, true);
log.info("Created BrooklynNode: "+bn);
// deploy
Task<?> t = bn.invoke(BrooklynNode.DEPLOY_BLUEPRINT, ConfigBag.newInstance()
.configure(BrooklynNode.DeployBlueprintEffector.BLUEPRINT_TYPE, TestApplication.class.getName())
.configure(BrooklynNode.DeployBlueprintEffector.BLUEPRINT_CONFIG, MutableMap.<String,Object>of("x", 1, "y", "Y"))
.getAllConfig());
log.info("Deployment result: "+t.getUnchecked());
MutableSet<Application> apps = MutableSet.copyOf( l.getManagementContext().getApplications() );
Assert.assertEquals(apps.size(), 2);
apps.remove(app);
Application newApp = Iterables.getOnlyElement(apps);
Entities.dumpInfo(newApp);
Assert.assertEquals(newApp.getConfig(new BasicConfigKey<Integer>(Integer.class, "x")), (Integer)1);
// check mirror
String newAppId = newApp.getId();
BrooklynEntityMirror mirror = app.createAndManageChild(EntitySpec.create(BrooklynEntityMirror.class)
.configure(BrooklynEntityMirror.MIRRORED_ENTITY_URL,
Urls.mergePaths(uri.toString(), "/v1/applications/"+newAppId+"/entities/"+newAppId))
.configure(BrooklynEntityMirror.MIRRORED_ENTITY_ID, newAppId)
.configure(BrooklynEntityMirror.POLL_PERIOD, Duration.millis(10)));
Entities.dumpInfo(mirror);
EntityTestUtils.assertAttributeEqualsEventually(mirror, Attributes.SERVICE_UP, true);
((EntityInternal)newApp).sensors().set(TestEntity.NAME, "foo");
EntityTestUtils.assertAttributeEqualsEventually(mirror, TestEntity.NAME, "foo");
log.info("Mirror successfully validated");
// also try deploying by invoking deploy through json
// (catch issues when effector params are map)
HttpClient client = HttpTool.httpClientBuilder().build();
HttpToolResponse result = HttpTool.httpPost(client, URI.create(Urls.mergePaths(uri.toString(), "/v1/applications/"+app.getId()+"/entities/"+bn.getId()
+"/effectors/deployBlueprint")),
MutableMap.of(com.google.common.net.HttpHeaders.CONTENT_TYPE, "application/json"),
Jsonya.newInstance()
.put("blueprintType", TestApplication.class.getName())
.put("blueprintConfig", MutableMap.of(TestEntity.CONF_NAME.getName(), "foo"))
.toString().getBytes());
log.info("Deploy effector invoked, result: "+result);
HttpTestUtils.assertHealthyStatusCode( result.getResponseCode() );
Repeater.create().every(Duration.millis(10)).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return l.getManagementContext().getApplications().size() == 3;
}
}).limitTimeTo(Duration.TEN_SECONDS).runRequiringTrue();
apps = MutableSet.copyOf( l.getManagementContext().getApplications() );
apps.removeAll( MutableSet.of(app, newApp) );
Application newApp2 = Iterables.getOnlyElement(apps);
Entities.dumpInfo(newApp2);
EntityTestUtils.assertAttributeEqualsEventually(newApp2, Attributes.SERVICE_UP, true);
Assert.assertEquals(newApp2.getConfig(TestEntity.CONF_NAME), "foo");
} finally {
l.destroyAll();
}
log.info("DONE");
}
}