/* * Copyright 2012-2013 iDA MediaFoundry (www.ida-mediafoundry.be) * * 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 be.idamediafoundry.sofa.livecycle.maven; import java.io.File; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.w3c.dom.Element; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointType; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointWithSettingsAndMappingType; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointWithSettingsType; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.InputParameterMappingType; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.OutputParameterMappingType; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config.Service; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config.Service.Configuration; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config.Service.Endpoints; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config.Service.Security; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.Config.Service.Configuration.Property; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointWithSettingsAndMappingType.InputParameterMapping; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointWithSettingsAndMappingType.OutputParameterMapping; import be.idamediafoundry.sofa.livecycle.maven.lca.configuration.EndpointWithSettingsType.Settings; import com.adobe.idp.dsc.clientsdk.ServiceClientFactory; import com.adobe.idp.dsc.registry.EndpointCategoryNotFoundException; import com.adobe.idp.dsc.registry.RegistryException; import com.adobe.idp.dsc.registry.endpoint.CreateEndpointCategoryInfo; import com.adobe.idp.dsc.registry.endpoint.CreateEndpointInfo; import com.adobe.idp.dsc.registry.endpoint.ModifyEndpointInfo; import com.adobe.idp.dsc.registry.endpoint.client.EndpointRegistryClient; import com.adobe.idp.dsc.registry.infomodel.Endpoint; import com.adobe.idp.dsc.registry.infomodel.EndpointCategory; import com.adobe.idp.dsc.registry.infomodel.ServiceConfiguration; import com.adobe.idp.dsc.registry.service.ModifyServiceConfigurationInfo; import com.adobe.idp.dsc.registry.service.ModifyServiceInfo; import com.adobe.idp.dsc.registry.service.client.ServiceRegistryClient; /** * Mojo to configure LiveCycle services. The configuration file contains information for setting/changing service * configuration and security options as well as add and/or change end point definitions. * * @goal configure */ public class ConfigurationMojo extends AbstractLiveCycleMojo { /** * The configuration file which should be used to configure the deployed services and their end points. * * @parameter property="liveCycle.lca.configurationFile" default-value="${basedir}/src/main/lc/config.xml" * @required */ private File configurationFile; /** * Constructor. */ public ConfigurationMojo() { super(); } /** * Constructor setting all common properties for configuring LiveCycle services. * * @param host the LiveCycle server host * @param port the LiveCycle server port * @param protocol the LiveCycle communication protocol * @param username the LiveCycle server user name * @param password the LiveCycle server password * @param configurationFile the configuration XML file holding the configuration parameters to be used to configure * the services. */ public ConfigurationMojo(final String host, final String port, final String protocol, final String username, final String password, final File configurationFile) { super(host, port, protocol, username, password); this.configurationFile = configurationFile; } /** * {@inheritDoc} */ public void execute() throws MojoExecutionException, MojoFailureException { if (configurationFile.exists()) { try { JAXBContext jaxbContext = JAXBContext.newInstance(Config.class.getPackage().getName()); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Config config = (Config) unmarshaller.unmarshal(configurationFile); ServiceClientFactory serviceClientFactory = getFactory(); List<Service> services = config.getService(); getLog().info("Setting configuration properties from " + configurationFile); for (Service service : services) { getLog().info("Configuring service " + service.getName()); ServiceRegistryClient serviceReg = new ServiceRegistryClient(serviceClientFactory); ServiceConfiguration serviceConfiguration = serviceReg.getHeadServiceConfiguration(service .getName()); ModifyServiceConfigurationInfo modifyServiceConfigurationInfo = new ModifyServiceConfigurationInfo(); String serviceId = serviceConfiguration.getServiceId(); modifyServiceConfigurationInfo.setServiceId(serviceId); modifyServiceConfigurationInfo.setMajorVersion(serviceConfiguration.getMajorVersion()); modifyServiceConfigurationInfo.setMinorVersion(serviceConfiguration.getMinorVersion()); handleSecurity(service, serviceReg, modifyServiceConfigurationInfo, serviceId); handleConfigurationParameters(service, modifyServiceConfigurationInfo); getLog().info("Consolidating for service " + serviceId); serviceReg.modifyConfiguration(modifyServiceConfigurationInfo); handleEndpointConfiguration(serviceClientFactory, service.getEndpoints(), serviceId); } } catch (RegistryException e) { getLog().debug(e); throw new MojoFailureException("Application manager failure while configuring: " + e.getMessage()); } catch (JAXBException e) { getLog().debug(e); throw new MojoFailureException("Configuration file could not be parsed: " + e.getMessage()); } } else { throw new MojoFailureException("No configuration file found (I was looking at " + configurationFile + "), no configuration set"); } } /** * Handle configuration parameters, setting them on the modify service configuration info as needed. * * @param service the service * @param modifyServiceConfigurationInfo the modify service condiguration info */ private void handleConfigurationParameters(final Service service, final ModifyServiceConfigurationInfo modifyServiceConfigurationInfo) { Configuration configuration = service.getConfiguration(); if (configuration != null) { List<Property> properties = configuration.getProperty(); for (Property property : properties) { getLog().debug("Configuring property " + property.getName() + " with value: " + property.getValue()); modifyServiceConfigurationInfo.setConfigParameterAsText(property.getName(), property.getValue()); } } } /** * Handle security configuration on a service. * * @param service the service element holding configuration parameters * @param serviceReg the service registry client * @param modifyServiceConfigurationInfo the modify service configuration info * @param serviceId the service identifier * @throws RegistryException when changing the security configuration fails */ private void handleSecurity(final Service service, final ServiceRegistryClient serviceReg, final ModifyServiceConfigurationInfo modifyServiceConfigurationInfo, final String serviceId) throws RegistryException { Security security = service.getSecurity(); if (security != null) { Boolean disableSecurity = security.isDisableSecurity(); if (disableSecurity == null) { disableSecurity = Boolean.FALSE; } ModifyServiceInfo modifyServiceInfo = new ModifyServiceInfo(); modifyServiceInfo.setId(serviceId); modifyServiceInfo.setSecurityEnabled(!disableSecurity.booleanValue()); serviceReg.modifyService(modifyServiceInfo); String runAs = security.getRunAs(); if (runAs != null) { if ("invoker".equalsIgnoreCase(runAs)) { modifyServiceConfigurationInfo.setRunAsConfiguration(ServiceConfiguration.RUN_AS_INVOKER); } else if ("system".equalsIgnoreCase(runAs)) { modifyServiceConfigurationInfo.setRunAsConfiguration(ServiceConfiguration.RUN_AS_SYSTEM); } else { modifyServiceConfigurationInfo.setRunAsConfiguration(runAs); } } } } /** * Handle end point configuration for the service identified by id with the given end point elements. * * @param serviceClientFactory the service client factory * @param endpoints the end point element container * @param serviceId the service identifier */ private void handleEndpointConfiguration(final ServiceClientFactory serviceClientFactory, final Endpoints endpoints, final String serviceId) { if (endpoints != null) { Boolean mustDeleteExistingEndpoints = endpoints.isRemoveExisting(); if (mustDeleteExistingEndpoints == null) { mustDeleteExistingEndpoints = Boolean.FALSE; } EndpointRegistryClient endPointClient = new EndpointRegistryClient(serviceClientFactory); getLog().info("Configuring endpoints for " + serviceId); @SuppressWarnings("unchecked") List<Endpoint> serviceEndpoints = endPointClient.getServiceEndpoints(serviceId, null, null); if (mustDeleteExistingEndpoints.booleanValue()) { for (Endpoint existingEndpoint : serviceEndpoints) { endPointClient.remove(existingEndpoint); } serviceEndpoints = null; } handleEndpointTypes(serviceId, endPointClient, serviceEndpoints, endpoints.getEjb(), "EJB"); handleEndpointTypes(serviceId, endPointClient, serviceEndpoints, endpoints.getSoap(), "SOAP"); handleEndpointTypes(serviceId, endPointClient, serviceEndpoints, endpoints.getRest(), "REST"); handleEndpointTypes(serviceId, endPointClient, serviceEndpoints, endpoints.getRemote(), "Remoting"); handleEndpointWithSettingsTypes(serviceId, endPointClient, serviceEndpoints, endpoints.getTaskManager(), "TaskManagerConnector"); handleEndpointWithSettingsAndMapping(serviceId, endPointClient, serviceEndpoints, endpoints.getEmail(), "Email"); handleEndpointWithSettingsAndMapping(serviceId, endPointClient, serviceEndpoints, endpoints.getWatchedFolder(), "WatchedFolder"); } else { getLog().info("No endpoint configuration found for " + serviceId); } } /** * Handle end point types, modifies/configures the end points on the service. * * @param serviceId the service id * @param endPointClient the end point client * @param serviceEndpoints the existing end points * @param endpointTypes the end point elements holding configuration parameters * @param type the type of the end point */ private void handleEndpointTypes(final String serviceId, final EndpointRegistryClient endPointClient, final List<Endpoint> serviceEndpoints, final List<EndpointType> endpointTypes, final String type) { if (endpointTypes != null) { for (EndpointType endpointType : endpointTypes) { String endpointName = calculateEndpointName(serviceId, endpointType); try { Endpoint endpoint = getExistingEndpointByNameAndType(serviceEndpoints, endpointName, type); if (endpoint == null) { CreateEndpointInfo createEndpointInfo = handleGeneralInfo(serviceId, type, endpointName, endpointType.getOperation(), endpointType.getDescription()); endpoint = endPointClient.createEndpoint(createEndpointInfo); } else { ModifyEndpointInfo endpointInfo = handleGeneralInfo(endpointName, endpointType.getOperation(), endpointType.getDescription(), endpoint); endpoint = endPointClient.modifyEndpoint(endpointInfo); } endPointClient.enable(endpoint); } catch (RegistryException e) { getLog().error("Could not configure endpoint " + endpointName + " for service " + serviceId, e); } } } } /** * Handle end points that need settings for the service identified by service id. * * @param serviceId the service id * @param endPointClient the end point client * @param serviceEndpoints the existing end points * @param endpointWithSettingTypes the end point elements holding configuration parameters * @param type the end point type */ private void handleEndpointWithSettingsTypes(final String serviceId, final EndpointRegistryClient endPointClient, final List<Endpoint> serviceEndpoints, final List<EndpointWithSettingsType> endpointWithSettingTypes, final String type) { if (endpointWithSettingTypes != null) { for (EndpointWithSettingsType endpointWithSettingsType : endpointWithSettingTypes) { String endpointName = calculateEndpointName(serviceId, endpointWithSettingsType); String category = endpointWithSettingsType.getCategory(); EndpointCategory endpointCategory = null; try { endpointCategory = handleCategory(endPointClient, category); } catch (RegistryException e) { getLog().error( "Could not configure category " + category + " for endpoint " + endpointName + " for service " + serviceId, e); } try { Endpoint endpoint = getExistingEndpointByNameAndType(serviceEndpoints, endpointName, type); if (endpoint == null) { CreateEndpointInfo createEndpointInfo = handleGeneralInfo(serviceId, type, endpointName, endpointWithSettingsType.getOperation(), endpointWithSettingsType.getDescription()); if (endpointCategory != null) { createEndpointInfo.setCategoryId(endpointCategory.getId()); } Settings settings = endpointWithSettingsType.getSettings(); handleSettings(createEndpointInfo, settings); endpoint = endPointClient.createEndpoint(createEndpointInfo); } else { ModifyEndpointInfo endpointInfo = handleGeneralInfo(endpointName, endpointWithSettingsType.getOperation(), endpointWithSettingsType.getDescription(), endpoint); if (endpointCategory != null) { endpointInfo.setCategoryId(endpointCategory.getId()); } Settings settings = endpointWithSettingsType.getSettings(); handleSettings(endpointInfo, settings); endpoint = endPointClient.modifyEndpoint(endpointInfo); } endPointClient.enable(endpoint); } catch (RegistryException e) { getLog().error("Could not configure endpoint " + endpointName + " for service " + serviceId, e); } } } } /** * Handle end points that need settings and parameters for the service identified by service id. * * @param serviceId the service id * @param endPointClient the end point client * @param serviceEndpoints the existing end points * @param endpointWithSettingsAndMappingTypes the end point elements holding configuration parameters * @param type the end point type */ private void handleEndpointWithSettingsAndMapping(final String serviceId, final EndpointRegistryClient endPointClient, final List<Endpoint> serviceEndpoints, final List<EndpointWithSettingsAndMappingType> endpointWithSettingsAndMappingTypes, final String type) { if (endpointWithSettingsAndMappingTypes != null) { for (EndpointWithSettingsAndMappingType endpointWithSettingsAndMappingType : endpointWithSettingsAndMappingTypes) { String endpointName = calculateEndpointName(serviceId, endpointWithSettingsAndMappingType); String operation = endpointWithSettingsAndMappingType.getOperation(); String description = endpointWithSettingsAndMappingType.getDescription(); try { Endpoint endpoint = getExistingEndpointByNameAndType(serviceEndpoints, endpointName, type); if (endpoint == null) { // Create new endpoint CreateEndpointInfo createEndpointInfo = handleGeneralInfo(serviceId, type, endpointName, operation, description); handleSettings(createEndpointInfo, endpointWithSettingsAndMappingType.getSettings()); handleInputParameterMapping(createEndpointInfo, endpointWithSettingsAndMappingType.getInputParameterMapping()); handleOutputParameterMapping(createEndpointInfo, endpointWithSettingsAndMappingType.getOutputParameterMapping()); endpoint = endPointClient.createEndpoint(createEndpointInfo); } else { ModifyEndpointInfo endpointInfo = handleGeneralInfo(endpointName, operation, description, endpoint); handleSettings(endpointInfo, endpointWithSettingsAndMappingType.getSettings()); handleInputParameterMapping(endpointInfo, endpointWithSettingsAndMappingType.getInputParameterMapping()); handleOutputParameterMapping(endpointInfo, endpointWithSettingsAndMappingType.getOutputParameterMapping()); endpoint = endPointClient.modifyEndpoint(endpointInfo); } endPointClient.enable(endpoint); } catch (RegistryException e) { getLog().error("Could not configure endpoint " + endpointName + " for service " + serviceId, e); } } } } /** * Retrieve an end point category based on the category name. If the category does not exist, a new one will be * created. * * @param endPointClient the end point client to retrieve or save the newly created category * @param category the name of the category to retrieve or create. * @return the end point category * @throws RegistryException when creating a new category fails */ private EndpointCategory handleCategory(final EndpointRegistryClient endPointClient, final String category) throws RegistryException { EndpointCategory endpointCategory = null; if (category != null && !"".equals(category)) { try { endpointCategory = endPointClient.getEndpointCategory(category); } catch (EndpointCategoryNotFoundException e) { CreateEndpointCategoryInfo catInfo = new CreateEndpointCategoryInfo(category, ""); try { endpointCategory = endPointClient.createEndpointCategory(catInfo); } catch (RegistryException re) { throw re; } } } return endpointCategory; } /** * Calculate the end point name. If the end point type contains a name, this is used, otherwise the service id is * used. * * @param serviceId the service id * @param endpointType the end point type * @return the name */ private String calculateEndpointName(final String serviceId, final EndpointType endpointType) { String endpointName = endpointType.getName(); if (endpointName == null) { endpointName = serviceId; } return endpointName; } /** * Generate modify end point info. * * @param endpointName the end point name * @param operation the operation * @param description the description * @param endpoint the end point element holding condiguration parameters * @return the modify end point info */ private ModifyEndpointInfo handleGeneralInfo(final String endpointName, final String operation, final String description, final Endpoint endpoint) { ModifyEndpointInfo endpointInfo = new ModifyEndpointInfo(); endpointInfo.setId(endpoint.getId()); endpointInfo.setDescription(description); endpointInfo.setName(endpointName); endpointInfo.setOperationName(operation); return endpointInfo; } /** * Generate create end point info. * * @param serviceId the service id * @param type the end point type * @param endpointName the end point name * @param operation the operation * @param description the description * @return the create end point info */ private CreateEndpointInfo handleGeneralInfo(final String serviceId, final String type, final String endpointName, final String operation, final String description) { CreateEndpointInfo createEndpointInfo = new CreateEndpointInfo(); createEndpointInfo.setConnectorId(type); createEndpointInfo.setDescription(description); createEndpointInfo.setName(endpointName); createEndpointInfo.setServiceId(serviceId); createEndpointInfo.setOperationName(operation); return createEndpointInfo; } /** * Add output parameter mappings to the modify end point info. * * @param endpointInfo the modify end point info * @param outputParameterMapping the output parameter mappings */ private void handleOutputParameterMapping(final ModifyEndpointInfo endpointInfo, final OutputParameterMapping outputParameterMapping) { if (outputParameterMapping != null) { List<OutputParameterMappingType> parameters = outputParameterMapping.getParameter(); for (OutputParameterMappingType parameter : parameters) { endpointInfo.setOutputParameterMapping(parameter.getName(), parameter.getDataType(), parameter.getValue()); } } } /** * Add output parameter mappings to the create end point info. * * @param createEndpointInfo the create end point info * @param outputParameterMapping the output parameter mappings */ private void handleOutputParameterMapping(final CreateEndpointInfo createEndpointInfo, final OutputParameterMapping outputParameterMapping) { if (outputParameterMapping != null) { List<OutputParameterMappingType> parameters = outputParameterMapping.getParameter(); for (OutputParameterMappingType parameter : parameters) { createEndpointInfo.setOutputParameterMapping(parameter.getName(), parameter.getDataType(), parameter.getValue()); } } } /** * Add input parameter mappings to the modify end point info. * * @param endpointInfo the modify end point info * @param inputParameterMapping the input parameter mappings */ private void handleInputParameterMapping(final ModifyEndpointInfo endpointInfo, final InputParameterMapping inputParameterMapping) { if (inputParameterMapping != null) { List<InputParameterMappingType> parameters = inputParameterMapping.getParameter(); for (InputParameterMappingType parameter : parameters) { endpointInfo.setInputParameterMapping(parameter.getName(), parameter.getDataType(), parameter.getMappingType(), parameter.getValue()); } } } /** * Add input parameter mappings to the create end point info. * * @param createEndpointInfo the create end point info * @param inputParameterMapping the input parameter mappings */ private void handleInputParameterMapping(final CreateEndpointInfo createEndpointInfo, final InputParameterMapping inputParameterMapping) { if (inputParameterMapping != null) { List<InputParameterMappingType> parameters = inputParameterMapping.getParameter(); for (InputParameterMappingType parameter : parameters) { createEndpointInfo.setInputParameterMapping(parameter.getName(), parameter.getDataType(), parameter.getMappingType(), parameter.getValue()); } } } /** * Add setting to the modify end point info. * * @param endpointInfo the modify end point info * @param settings the settings */ private void handleSettings(final ModifyEndpointInfo endpointInfo, final Settings settings) { if (settings != null) { List<Element> settingElements = settings.getAny(); for (Element element : settingElements) { String name = element.getNodeName(); String value = element.getTextContent(); endpointInfo.setConfigParameterAsText(name, value); } } } /** * Add settings to the create end point info. * * @param createEndpointInfo the create end point info * @param settings the settings */ private void handleSettings(final CreateEndpointInfo createEndpointInfo, final Settings settings) { if (settings != null) { List<Element> settingElements = settings.getAny(); for (Element element : settingElements) { String name = element.getNodeName(); String value = element.getTextContent(); createEndpointInfo.setConfigParameterAsText(name, value); } } } /** * Get an existing end point by name and type. * * @param existingEndpoints all existing end points * @param endpointName the end point name * @param type the type * @return The exiting end point matching the name and type, or null if not found.s */ private Endpoint getExistingEndpointByNameAndType(final List<Endpoint> existingEndpoints, final String endpointName, final String type) { Endpoint endpoint = null; if (existingEndpoints != null) { for (Endpoint existingEndpoint : existingEndpoints) { if (existingEndpoint.getConnectorId().equals(type) && existingEndpoint.getName().equals(endpointName)) { // Modify existing endpoint endpoint = existingEndpoint; break; } } } return endpoint; } }