| /* |
| * 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.knox.gateway.util; |
| |
| import com.fasterxml.jackson.annotation.JsonInclude; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import org.apache.commons.io.FilenameUtils; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.knox.gateway.GatewayMessages; |
| import org.apache.knox.gateway.i18n.messages.MessagesFactory; |
| import org.apache.knox.gateway.model.DescriptorConfiguration; |
| import org.apache.knox.gateway.model.ProviderConfiguration; |
| import org.apache.knox.gateway.model.Topology; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.XMLConstants; |
| import javax.xml.bind.JAXBContext; |
| import javax.xml.bind.JAXBException; |
| import javax.xml.bind.Unmarshaller; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.stream.StreamSource; |
| import javax.xml.validation.Schema; |
| import javax.xml.validation.SchemaFactory; |
| import javax.xml.validation.Validator; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.nio.file.Files; |
| import java.nio.file.Paths; |
| import java.util.Locale; |
| |
| /** |
| * A helper class to convert topology xml file to descriptor and provider |
| * model. |
| */ |
| public class TopologyToDescriptor { |
| |
| private static final GatewayMessages LOG = MessagesFactory |
| .get(GatewayMessages.class); |
| private static final ObjectMapper mapper = new ObjectMapper(); |
| private static final String SCHEMA_FILE = "/conf/topology-v1.xsd"; |
| |
| static { |
| /* skip printing out null fields */ |
| mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| } |
| |
| private String topologyPath; |
| private String providerName; |
| private String descriptorName; |
| private String discoveryUrl; |
| private String discoveryUser; |
| private String discoveryPasswordAlias; |
| private String discoveryType; |
| private String cluster; |
| private String providerConfigDir; |
| private String descriptorConfigDir; |
| private boolean force; |
| |
| public TopologyToDescriptor() { |
| super(); |
| } |
| |
| /** |
| * A function that validates the given topology |
| */ |
| private void validateTopology(final String xsd, final String topologyFile) |
| throws IOException, SAXException { |
| try (InputStream topologyFileStream = Files |
| .newInputStream(Paths.get(topologyFile))) { |
| final Source xmlSource = new StreamSource(topologyFileStream); |
| final Schema schema = getSchema(xsd); |
| final Validator validator = schema.newValidator(); |
| validator.validate(xmlSource); |
| } catch (IOException | SAXException e) { |
| LOG.errorValidatingTopology(topologyFile); |
| throw e; |
| } |
| } |
| |
| private Topology parseTopology(final String xsd, final String topologyFile) |
| throws JAXBException, SAXException, IOException { |
| try (InputStream topologyFileStream = Files |
| .newInputStream(Paths.get(topologyFile))) { |
| final Schema schema = getSchema(xsd); |
| final JAXBContext jc = JAXBContext.newInstance(Topology.class); |
| final Unmarshaller unmarshaller = jc.createUnmarshaller(); |
| unmarshaller.setSchema(schema); |
| return (Topology) unmarshaller.unmarshal(topologyFileStream); |
| } catch (SAXException | JAXBException | IOException e) { |
| LOG.errorParsingTopology(topologyFile); |
| throw e; |
| } |
| } |
| |
| private Schema getSchema(final String xsd) throws SAXException { |
| final SchemaFactory schemaFactory = SchemaFactory |
| .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); |
| final URL schemaUrl = TopologyToDescriptor.class.getResource(xsd); |
| return schemaFactory.newSchema(schemaUrl); |
| } |
| |
| /** |
| * Validate topology |
| * |
| * @throws IOException Exception on validating file. |
| * @throws SAXException Exception on parsing XML. |
| */ |
| public void validate() throws IOException, SAXException { |
| validateTopology(SCHEMA_FILE, topologyPath); |
| } |
| |
| /** |
| * Convert topology to provider and descriptor |
| * |
| * @throws IOException Exception on validating file. |
| * @throws JAXBException Exception on parsing XML. |
| * @throws SAXException Exception on parsing XML. |
| */ |
| public void convert() throws IOException, JAXBException, SAXException { |
| final Topology topology = parseTopology(SCHEMA_FILE, topologyPath); |
| saveProvider(topology); |
| saveDescriptor(topology, providerName); |
| } |
| |
| private void saveProvider(final Topology topology) throws IOException { |
| try { |
| final ProviderConfiguration provider = new ProviderConfiguration(); |
| if (topology.getProviders() != null) { |
| provider.setProviders(topology.getProviders()); |
| } |
| |
| final File providerFile = new File( |
| providerConfigDir + File.separator + providerName); |
| |
| fileCheck(providerFile); |
| |
| mapper.writerWithDefaultPrettyPrinter() |
| .writeValue(providerFile, provider); |
| } catch (final IOException e) { |
| LOG.errorSavingProviderConfiguration(providerName, topologyPath, |
| e.toString()); |
| throw e; |
| } |
| } |
| |
| private void saveDescriptor(final Topology topology, |
| final String providerName) throws IOException { |
| final DescriptorConfiguration descriptorConfiguration = new DescriptorConfiguration(); |
| |
| descriptorConfiguration |
| .setProviderConfig(FilenameUtils.removeExtension(providerName)); |
| |
| if (!StringUtils.isBlank(discoveryUrl)) { |
| descriptorConfiguration.setDiscoveryAddress(discoveryUrl); |
| } |
| |
| if (!StringUtils.isBlank(discoveryUser)) { |
| descriptorConfiguration.setDiscoveryUser(discoveryUser); |
| } |
| |
| if (!StringUtils.isBlank(discoveryPasswordAlias)) { |
| descriptorConfiguration.setDiscoveryPasswordAlias(discoveryPasswordAlias); |
| } |
| |
| if (!StringUtils.isBlank(discoveryType)) { |
| descriptorConfiguration.setDiscoveryType(discoveryType); |
| } |
| |
| if (!StringUtils.isBlank(cluster)) { |
| descriptorConfiguration.setCluster(cluster); |
| } |
| |
| if (topology.getName() != null) { |
| descriptorConfiguration.setName(topology.getName()); |
| } |
| |
| if (topology.getApplications() != null) { |
| descriptorConfiguration.setApplications(topology.getApplications()); |
| } |
| |
| if (topology.getServices() != null) { |
| descriptorConfiguration.setServices(topology.getServices()); |
| } |
| |
| final File descriptorFile = new File( |
| descriptorConfigDir + File.separator + descriptorName); |
| |
| fileCheck(descriptorFile); |
| |
| try { |
| mapper.writerWithDefaultPrettyPrinter() |
| .writeValue(descriptorFile, descriptorConfiguration); |
| } catch (IOException e) { |
| LOG.errorSavingDescriptorConfiguration(descriptorName, topologyPath, |
| e.toString()); |
| throw e; |
| } |
| } |
| |
| /** |
| * Check whether the file exists and can be overwritten. |
| * |
| * @param file |
| * @throws IOException |
| */ |
| private void fileCheck(final File file) throws IOException { |
| if (!force && file.exists()) { |
| throw new IOException(String |
| .format(Locale.ROOT, "File %s already exist, use --force option to overwrite.", |
| file.getAbsolutePath())); |
| } |
| /* make sure file and directories are in place */ |
| Files.createDirectories(file.toPath().getParent()); |
| file.createNewFile(); |
| } |
| |
| public void setDiscoveryUrl(String discoveryUrl) { |
| this.discoveryUrl = discoveryUrl; |
| } |
| |
| public void setDiscoveryUser(String discoveryUser) { |
| this.discoveryUser = discoveryUser; |
| } |
| |
| public void setDiscoveryPasswordAlias(String discoveryPasswordAlias) { |
| this.discoveryPasswordAlias = discoveryPasswordAlias; |
| } |
| |
| public void setDiscoveryType(String discoveryType) { |
| this.discoveryType = discoveryType; |
| } |
| |
| public void setCluster(String cluster) { |
| this.cluster = cluster; |
| } |
| |
| public void setTopologyPath(String topologyPath) { |
| this.topologyPath = topologyPath; |
| } |
| |
| public void setProviderName(String providerName) { |
| this.providerName = providerName; |
| } |
| |
| public void setDescriptorName(String descriptorName) { |
| this.descriptorName = descriptorName; |
| } |
| |
| public void setProviderConfigDir(String providerConfigDir) { |
| this.providerConfigDir = providerConfigDir; |
| } |
| |
| public void setDescriptorConfigDir(String descriptorConfigDir) { |
| this.descriptorConfigDir = descriptorConfigDir; |
| } |
| |
| public void setForce(boolean force) { |
| this.force = force; |
| } |
| } |