Java tutorial
/* * Copyright 2015 VMware, Inc. All Rights Reserved. * * Licensed 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 com.vmware.photon.controller.apife; import com.vmware.photon.controller.api.common.filters.LoggingFilter; import com.vmware.photon.controller.api.common.filters.UrlTrailingSlashFilter; import com.vmware.photon.controller.api.common.jackson.GuiceModule; import com.vmware.photon.controller.api.common.providers.ConstraintViolationExceptionMapper; import com.vmware.photon.controller.api.common.providers.ExternalExceptionMapper; import com.vmware.photon.controller.api.common.providers.InvalidEntityExceptionMapper; import com.vmware.photon.controller.api.common.providers.JsonProcessingExceptionMapper; import com.vmware.photon.controller.api.common.providers.LoggingExceptionMapper; import com.vmware.photon.controller.api.common.providers.WebApplicationExceptionMapper; import com.vmware.photon.controller.apife.auth.AuthFilter; import com.vmware.photon.controller.apife.config.ApiFeConfiguration; import com.vmware.photon.controller.apife.config.AuthConfig; import com.vmware.photon.controller.apife.config.ConfigurationUtils; import com.vmware.photon.controller.apife.filter.PauseFilter; import com.vmware.photon.controller.apife.resources.AuthResource; import com.vmware.photon.controller.apife.resources.ClusterResizeResource; import com.vmware.photon.controller.apife.resources.ClusterResource; import com.vmware.photon.controller.apife.resources.ClusterVmsResource; import com.vmware.photon.controller.apife.resources.DatastoreResource; import com.vmware.photon.controller.apife.resources.DatastoresResource; import com.vmware.photon.controller.apife.resources.DeploymentAdminGroupsResource; import com.vmware.photon.controller.apife.resources.DeploymentHostsResource; import com.vmware.photon.controller.apife.resources.DeploymentResource; import com.vmware.photon.controller.apife.resources.DeploymentVmsResource; import com.vmware.photon.controller.apife.resources.DeploymentsResource; import com.vmware.photon.controller.apife.resources.DiskResource; import com.vmware.photon.controller.apife.resources.DiskTasksResource; import com.vmware.photon.controller.apife.resources.FlavorResource; import com.vmware.photon.controller.apife.resources.FlavorTasksResource; import com.vmware.photon.controller.apife.resources.FlavorsResource; import com.vmware.photon.controller.apife.resources.HostResource; import com.vmware.photon.controller.apife.resources.HostTasksResource; import com.vmware.photon.controller.apife.resources.HostVmsResource; import com.vmware.photon.controller.apife.resources.HostsResource; import com.vmware.photon.controller.apife.resources.ImageResource; import com.vmware.photon.controller.apife.resources.ImageTasksResource; import com.vmware.photon.controller.apife.resources.ImagesResource; import com.vmware.photon.controller.apife.resources.NetworkPortGroupsSetResource; import com.vmware.photon.controller.apife.resources.NetworkResource; import com.vmware.photon.controller.apife.resources.NetworksResource; import com.vmware.photon.controller.apife.resources.PortGroupResource; import com.vmware.photon.controller.apife.resources.PortGroupsResource; import com.vmware.photon.controller.apife.resources.ProjectClustersResource; import com.vmware.photon.controller.apife.resources.ProjectDisksResource; import com.vmware.photon.controller.apife.resources.ProjectResource; import com.vmware.photon.controller.apife.resources.ProjectSecurityGroupsResource; import com.vmware.photon.controller.apife.resources.ProjectTasksResource; import com.vmware.photon.controller.apife.resources.ProjectVmsResource; import com.vmware.photon.controller.apife.resources.ResourceTicketResource; import com.vmware.photon.controller.apife.resources.ResourceTicketTasksResource; import com.vmware.photon.controller.apife.resources.StatusResource; import com.vmware.photon.controller.apife.resources.TaskResource; import com.vmware.photon.controller.apife.resources.TasksResource; import com.vmware.photon.controller.apife.resources.TenantProjectsResource; import com.vmware.photon.controller.apife.resources.TenantResource; import com.vmware.photon.controller.apife.resources.TenantResourceTicketsResource; import com.vmware.photon.controller.apife.resources.TenantSecurityGroupsResource; import com.vmware.photon.controller.apife.resources.TenantTasksResource; import com.vmware.photon.controller.apife.resources.TenantsResource; import com.vmware.photon.controller.apife.resources.TopologyResource; import com.vmware.photon.controller.apife.resources.VmDiskAttachResource; import com.vmware.photon.controller.apife.resources.VmDiskDetachResource; import com.vmware.photon.controller.apife.resources.VmIsoAttachResource; import com.vmware.photon.controller.apife.resources.VmIsoDetachResource; import com.vmware.photon.controller.apife.resources.VmMetadataSetResource; import com.vmware.photon.controller.apife.resources.VmMksTicketResource; import com.vmware.photon.controller.apife.resources.VmNetworksResource; import com.vmware.photon.controller.apife.resources.VmOperationsResource; import com.vmware.photon.controller.apife.resources.VmResource; import com.vmware.photon.controller.apife.resources.VmTagsResource; import com.vmware.photon.controller.apife.resources.VmTasksResource; import com.vmware.photon.controller.common.metrics.GraphiteConfig; import com.vmware.photon.controller.common.zookeeper.ServiceNode; import com.vmware.photon.controller.common.zookeeper.ServiceNodeFactory; import com.vmware.photon.controller.common.zookeeper.ServiceNodeUtils; import com.vmware.photon.controller.common.zookeeper.ZookeeperModule; import com.vmware.photon.controller.swagger.resources.SwaggerJsonListing; import com.google.common.collect.ImmutableList; import com.google.inject.Injector; import com.hubspot.dropwizard.guice.GuiceBundle; import io.dropwizard.Application; import io.dropwizard.assets.AssetsBundle; import io.dropwizard.configuration.ConfigurationException; import io.dropwizard.db.DataSourceFactory; import io.dropwizard.hibernate.HibernateBundle; import io.dropwizard.hibernate.SessionFactoryFactory; import io.dropwizard.jetty.HttpConnectorFactory; import io.dropwizard.migrations.MigrationsBundle; import io.dropwizard.server.DefaultServerFactory; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.hibernate.EmptyInterceptor; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.ImprovedNamingStrategy; import org.hibernate.type.Type; import org.reflections.Reflections; import javax.persistence.Entity; import javax.servlet.DispatcherType; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorFactory; import javax.validation.Validation; import javax.validation.ValidatorFactory; import java.io.IOException; import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; /** * This is the main API Front End Service. When an instance is launched, this is the boot class and the .run * method is the method that fires up the server. */ public class ApiFeService extends Application<ApiFeConfiguration> { public static final String SWAGGER_VERSION = "1.2"; private static final long retryIntervalMsec = TimeUnit.SECONDS.toMillis(30); private static ApiFeConfiguration apiFeConfiguration; private Injector injector; private ApiFeModule apiModule; private ZookeeperModule zookeeperModule; private HibernateBundle<ApiFeConfiguration> hibernateBundle; public static void main(String[] args) throws Exception { setupApiFeConfigurationForServerCommand(args); new ApiFeService().run(args); } /** * Best effort to parse configuration file as in `bin/management server /etc/esxcloud/management-api.yml`. * It does not work with commands such as * `management db migrate /etc/esxcloud/management-api.yml` * as in {@link io.dropwizard.migrations.DbCommand} */ private static void setupApiFeConfigurationForServerCommand(String[] args) throws IOException, ConfigurationException { if (args.length == 2 && "server".equals(args[0])) { apiFeConfiguration = ConfigurationUtils.parseConfiguration(args[1]); } } @Override public void initialize(Bootstrap<ApiFeConfiguration> bootstrap) { bootstrap.addBundle(new MigrationsBundle<ApiFeConfiguration>() { @Override public DataSourceFactory getDataSourceFactory(ApiFeConfiguration configuration) { return configuration.getDataSourceFactory(); } }); bootstrap.addBundle(new AssetsBundle("/assets", "/api/", "index.html")); apiModule = new ApiFeModule(); zookeeperModule = new ZookeeperModule(); apiModule.setConfiguration(apiFeConfiguration); zookeeperModule.setConfig(apiFeConfiguration.getZookeeper()); zookeeperModule.setConfig(apiFeConfiguration.getZookeeper()); GuiceBundle<ApiFeConfiguration> guiceBundle = getGuiceBundle(); bootstrap.addBundle(guiceBundle); injector = guiceBundle.getInjector(); } @Override public void run(ApiFeConfiguration configuration, Environment environment) throws Exception { environment.jersey().register(PauseFilter.class); final AuthConfig authConfig = configuration.getAuth(); if (authConfig.isAuthEnabled()) { environment.jersey().register(AuthFilter.class); } environment.jersey().register(new AbstractBinder() { @Override protected void configure() { bind(new AuthResource(authConfig)).to(AuthResource.class); } }); environment.jersey().register(AuthResource.class); registerResourcesWithSwagger(configuration, environment); ValidatorFactory validatorFactory = Validation.byDefaultProvider().configure() .constraintValidatorFactory(new ConstraintValidatorFactory() { @Override public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { return injector.getInstance(key); } @Override public void releaseInstance(ConstraintValidator<?, ?> constraintValidator) { // do nothing } }).buildValidatorFactory(); environment.setValidator(validatorFactory.getValidator()); environment.getObjectMapper().registerModule(injector.getInstance(GuiceModule.class)); environment.jersey().register(injector.getInstance(ExternalExceptionMapper.class)); environment.jersey().register(injector.getInstance(InvalidEntityExceptionMapper.class)); environment.jersey().register(injector.getInstance(ConstraintViolationExceptionMapper.class)); environment.jersey().register(injector.getInstance(JsonProcessingExceptionMapper.class)); environment.jersey().register(injector.getInstance(LoggingExceptionMapper.class)); environment.jersey().register(injector.getInstance(WebApplicationExceptionMapper.class)); environment.servlets().addFilter("LoggingFilter", injector.getInstance(LoggingFilter.class)) .addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); environment.servlets() .addFilter("UrlTrailingSlashFilter", injector.getInstance(UrlTrailingSlashFilter.class)) .addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/api"); GraphiteConfig graphite = configuration.getGraphite(); if (graphite != null) { graphite.enable(); } HttpConnectorFactory httpConnectorFactory = (HttpConnectorFactory) ((DefaultServerFactory) configuration .getServerFactory()).getApplicationConnectors().get(0); registerWithZookeeper(injector.getInstance(ServiceNodeFactory.class), configuration.getRegistrationAddress(), httpConnectorFactory.getPort()); } private void registerWithZookeeper(ServiceNodeFactory serviceNodeFactory, String registrationIpAddress, int port) { InetSocketAddress registrationSocketAddress = new InetSocketAddress(registrationIpAddress, port); ServiceNode serviceNode = serviceNodeFactory.createSimple("apife", registrationSocketAddress); ServiceNodeUtils.joinService(serviceNode, retryIntervalMsec); } private void registerResourcesWithSwagger(ApiFeConfiguration configuration, Environment environment) { List<Class<?>> resources = new ArrayList<>(); resources.add(AuthResource.class); resources.add(ClusterResource.class); resources.add(ClusterResizeResource.class); resources.add(ClusterVmsResource.class); resources.add(DatastoreResource.class); resources.add(DatastoresResource.class); resources.add(DeploymentHostsResource.class); resources.add(DeploymentResource.class); resources.add(DeploymentsResource.class); resources.add(DeploymentVmsResource.class); resources.add(DeploymentAdminGroupsResource.class); resources.add(DiskResource.class); resources.add(DiskTasksResource.class); resources.add(FlavorResource.class); resources.add(FlavorsResource.class); resources.add(FlavorTasksResource.class); resources.add(HostResource.class); resources.add(HostsResource.class); resources.add(HostTasksResource.class); resources.add(HostVmsResource.class); resources.add(NetworkPortGroupsSetResource.class); resources.add(NetworkResource.class); resources.add(NetworksResource.class); resources.add(ImageResource.class); resources.add(ImagesResource.class); resources.add(ImageTasksResource.class); resources.add(ProjectClustersResource.class); resources.add(ProjectDisksResource.class); resources.add(PortGroupResource.class); resources.add(PortGroupsResource.class); resources.add(ProjectResource.class); resources.add(ProjectTasksResource.class); resources.add(ProjectVmsResource.class); resources.add(ProjectSecurityGroupsResource.class); resources.add(ResourceTicketResource.class); resources.add(ResourceTicketTasksResource.class); resources.add(StatusResource.class); resources.add(TaskResource.class); resources.add(TasksResource.class); resources.add(TenantProjectsResource.class); resources.add(TenantResource.class); resources.add(TenantResourceTicketsResource.class); resources.add(TenantsResource.class); resources.add(TenantTasksResource.class); resources.add(TenantSecurityGroupsResource.class); resources.add(TopologyResource.class); resources.add(VmDiskAttachResource.class); resources.add(VmDiskDetachResource.class); resources.add(VmIsoAttachResource.class); resources.add(VmIsoDetachResource.class); resources.add(VmMetadataSetResource.class); resources.add(VmMksTicketResource.class); resources.add(VmNetworksResource.class); resources.add(VmOperationsResource.class); resources.add(VmResource.class); resources.add(VmTagsResource.class); resources.add(VmTasksResource.class); environment.jersey().register(new SwaggerJsonListing(resources, SWAGGER_VERSION, "v1")); } private GuiceBundle<ApiFeConfiguration> getGuiceBundle() { return GuiceBundle.<ApiFeConfiguration>newBuilder().setConfigClass(ApiFeConfiguration.class) .addModule(apiModule).addModule(zookeeperModule).enableAutoConfig(getClass().getPackage().getName()) .build(); } private HibernateBundle<ApiFeConfiguration> getHibernateBundle() { Reflections reflections = new Reflections(getClass().getPackage().getName()); Set<Class<?>> entities = reflections.getTypesAnnotatedWith(Entity.class); ImmutableList<Class<?>> immutableEntitiesList = ImmutableList.copyOf(entities); Reflections commonReflections = new Reflections("com.vmware.esxcloud.api.common"); entities.addAll(commonReflections.getTypesAnnotatedWith(Entity.class)); return new HibernateBundle<ApiFeConfiguration>(immutableEntitiesList, new SessionFactoryFactory()) { @Override public DataSourceFactory getDataSourceFactory(ApiFeConfiguration configuration) { return configuration.getDataSourceFactory(); } @Override public void configure(Configuration configuration) { configuration.setNamingStrategy(ImprovedNamingStrategy.INSTANCE); configuration.setInterceptor(new EmptyInterceptor() { @Override public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { injector.injectMembers(entity); return true; } }); } }; } }