/* * 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.rest.resources; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.sun.jersey.api.core.ClassNamesResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.Test; import org.apache.brooklyn.rest.BrooklynRestApi; import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest; import com.sun.jersey.test.framework.AppDescriptor; import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; import com.sun.jersey.test.framework.spi.container.TestContainerException; import com.sun.jersey.test.framework.spi.container.TestContainerFactory; import com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory; import io.swagger.annotations.Api; import io.swagger.models.Info; import io.swagger.models.Operation; import io.swagger.models.Path; import io.swagger.models.Swagger; import java.util.Collection; import org.apache.brooklyn.rest.api.CatalogApi; import org.apache.brooklyn.rest.api.EffectorApi; import org.apache.brooklyn.rest.api.EntityApi; import org.apache.brooklyn.rest.filter.SwaggerFilter; import org.apache.brooklyn.rest.util.ShutdownHandlerProvider; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; /** * @author Adam Lowe */ @Test(singleThreaded = true) public class ApidocResourceTest extends BrooklynRestResourceTest { private static final Logger log = LoggerFactory.getLogger(ApidocResourceTest.class); @Override protected JerseyTest createJerseyTest() { return new JerseyTest() { @Override protected AppDescriptor configure() { return new WebAppDescriptor.Builder( ImmutableMap.of( ServletContainer.RESOURCE_CONFIG_CLASS, ClassNamesResourceConfig.class.getName(), ClassNamesResourceConfig.PROPERTY_CLASSNAMES, getResourceClassnames())) .addFilter(SwaggerFilter.class, "SwaggerFilter").build(); } @Override protected TestContainerFactory getTestContainerFactory() throws TestContainerException { return new GrizzlyWebTestContainerFactory(); } private String getResourceClassnames() { Iterable<String> classnames = Collections2.transform(config.getClasses(), new Function<Class, String>() { @Override public String apply(Class clazz) { return clazz.getName(); } }); classnames = Iterables.concat(classnames, Collections2.transform(config.getSingletons(), new Function<Object, String>() { @Override public String apply(Object singleton) { return singleton.getClass().getName(); } })); return Joiner.on(';').join(classnames); } }; } @Override protected void addBrooklynResources() { for (Object o : BrooklynRestApi.getApidocResources()) { addResource(o); } super.addBrooklynResources(); } @Test(enabled = false) public void testRootSerializesSensibly() throws Exception { String data = resource("/v1/apidoc/swagger.json").get(String.class); log.info("apidoc gives: "+data); // make sure no scala gets in assertFalse(data.contains("$")); assertFalse(data.contains("scala")); // make sure it's an appropriate swagger 2.0 json Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); assertEquals(swagger.getSwagger(), "2.0"); } @Test(enabled = false) public void testCountRestResources() throws Exception { Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); assertEquals(swagger.getTags().size(), 1 + Iterables.size(BrooklynRestApi.getBrooklynRestResources())); } @Test(enabled = false) public void testApiDocDetails() throws Exception { Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); Collection<Operation> operations = getTaggedOperations(swagger, ApidocResource.class.getAnnotation(Api.class).value()); assertEquals(operations.size(), 2, "ops="+operations); } @Test(enabled = false) public void testEffectorDetails() throws Exception { Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); Collection<Operation> operations = getTaggedOperations(swagger, EffectorApi.class.getAnnotation(Api.class).value()); assertEquals(operations.size(), 2, "ops="+operations); } @Test(enabled = false) public void testEntityDetails() throws Exception { Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); Collection<Operation> operations = getTaggedOperations(swagger, EntityApi.class.getAnnotation(Api.class).value()); assertEquals(operations.size(), 14, "ops="+operations); } @Test(enabled = false) public void testCatalogDetails() throws Exception { Swagger swagger = resource("/v1/apidoc/swagger.json").get(Swagger.class); Collection<Operation> operations = getTaggedOperations(swagger, CatalogApi.class.getAnnotation(Api.class).value()); assertEquals(operations.size(), 22, "ops="+operations); } /** * Retrieves all operations tagged the given tag from the given swagger spec. */ private Collection<Operation> getTaggedOperations(Swagger swagger, final String requiredTag) { Iterable<Operation> allOperations = Iterables.concat(Collections2.transform(swagger.getPaths().values(), new Function<Path, Collection<Operation>>() { @Override public Collection<Operation> apply(Path path) { return path.getOperations(); } })); return Collections2.filter(ImmutableList.copyOf(allOperations), new Predicate<Operation>() { @Override public boolean apply(Operation operation) { return operation.getTags().contains(requiredTag); } }); } }