All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vmware.photon.controller.model.util.StartServicesHelper Maven / Gradle / Ivy

/*
 * Copyright (c) 2015-2016 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.model.util;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.function.Supplier;

import com.vmware.xenon.common.FactoryService;
import com.vmware.xenon.common.Service;
import com.vmware.xenon.common.ServiceHost;
import com.vmware.xenon.common.UriUtils;

/**
 * The goal of this helper class is to ease the start of family of services (such as
 * {@link com.vmware.photon.controller.model.PhotonModelServices}) and at the same time expose their
 * public links.
 *
 * 

* Impl notes: As of now the approach is to create {@code public static String[] LINKS} var holding * services links and {@code public static void startServices(ServiceHost host)} method starting all * the services. And the expectation is that the set of links and the set of started services should * be the same. In order to enforce that we introduce {@link ServiceMetadata} that is used to * calculate the links and start the services, thus the client of the class is focused on just * describing its set of services. */ public class StartServicesHelper { /** * Use this method to get the set of service links. * * @see com.vmware.photon.controller.model.PhotonModelServices#LINKS */ public static String[] getServiceLinks(ServiceMetadata[] servicesMetadata) { return Arrays.stream(servicesMetadata) .map(ServiceMetadata::getLink) .toArray(String[]::new); } /** * Use this method to start the set of services. * * @see com.vmware.photon.controller.model.PhotonModelServices#startServices(ServiceHost) */ public static void startServices(ServiceHost host, ServiceMetadata[] servicesMetadata) { Arrays.stream(servicesMetadata).forEach(serviceDesc -> serviceDesc.start(host)); } /** * A meta-data describing a service including: *

    *
  • service type (such as service or factory)
  • *
  • service class
  • *
  • service instantiation logic (applicable for factory services)
  • *
*/ public static class ServiceMetadata { /** * Create meta-data for a {@link Service}. */ public static ServiceMetadata service(Class serviceClass) { final ServiceMetadata serviceDesc = new ServiceMetadata(); serviceDesc.isServiceOrFactory = true; serviceDesc.serviceClass = serviceClass; return serviceDesc; } /** * Create meta-data for a {@link FactoryService}. */ public static ServiceMetadata factoryService( Class serviceClass, Supplier factoryCreator) { final ServiceMetadata serviceDesc = new ServiceMetadata(); serviceDesc.isServiceOrFactory = false; serviceDesc.serviceClass = serviceClass; serviceDesc.factoryCreator = factoryCreator; return serviceDesc; } /** * Create meta-data for a {@link FactoryService}. */ public static ServiceMetadata factoryService(Class serviceClass) { return factoryService(serviceClass, null); } // true = service; false = factory service private boolean isServiceOrFactory; private Class serviceClass; private Supplier factoryCreator; /** * Get (through reflection by analogy with UriUtils.buildFactoryUri) the SELF_LINK of a * service or the FACTORY_LINK of a factory service. */ public String getLink() { String selfLinkOrFactoryLinkName = this.isServiceOrFactory ? UriUtils.FIELD_NAME_SELF_LINK : UriUtils.FIELD_NAME_FACTORY_LINK; try { Field selfLinkOrFactoryLink = this.serviceClass .getDeclaredField(selfLinkOrFactoryLinkName); if (selfLinkOrFactoryLink != null) { selfLinkOrFactoryLink.setAccessible(true); return selfLinkOrFactoryLink.get(null).toString(); } } catch (Exception e) { } throw new IllegalAccessError(String.format( "'%s' service does not have public static '%s' field", this.serviceClass, selfLinkOrFactoryLinkName)); } /** * Start the service considering its type. */ public void start(ServiceHost serviceHost) { if (this.isServiceOrFactory) { serviceHost.startService(newServiceInstance()); } else { if (this.factoryCreator == null) { serviceHost.startFactory(newServiceInstance()); } else { serviceHost.startFactory(this.serviceClass, this.factoryCreator); } } } private Service newServiceInstance() { try { return this.serviceClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new IllegalAccessError( "Failed to create an instance of " + this.serviceClass); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy