RYA-448 Implement JAXB marshalling code for the Query Manager's XML configuration file.
Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/c1ccde80 Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/c1ccde80 Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/c1ccde80 Branch: refs/heads/master Commit: c1ccde80bbd898f6051da8bdedacac3c53e14539 Parents: 9e8a27c Author: kchilton2 <[email protected]> Authored: Tue Jan 23 15:50:17 2018 -0500 Committer: Valiyil <[email protected]> Committed: Fri Mar 9 12:59:41 2018 -0500 ---------------------------------------------------------------------- extras/rya.streams/query-manager/pom.xml | 52 ++++++++++++- .../query-manager/src/license/header.txt | 16 ++++ .../src/main/config/configuration.xml | 51 ++++++++++++ .../xml/QueryManagerConfigUnmarshaller.java | 78 +++++++++++++++++++ .../src/main/xsd/QueryManagerConfig.xsd | 81 ++++++++++++++++++++ .../xml/QueryManagerConfigMarshallerTest.java | 78 +++++++++++++++++++ 6 files changed, 355 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/pom.xml ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/pom.xml b/extras/rya.streams/query-manager/pom.xml index 3a13c6a..76e521d 100644 --- a/extras/rya.streams/query-manager/pom.xml +++ b/extras/rya.streams/query-manager/pom.xml @@ -48,7 +48,57 @@ under the License. </dependency> </dependencies> <build> + <!-- Add the XSD directory as a resource so that it will be packaged in the jar. + - Required so that the marshalling code is able to find the schema it is + - validating XML against. --> + <resources> + <resource> + <directory>src/main/xsd</directory> + </resource> + </resources> + <plugins> + <!-- Generate the XML marshalling java code from the XSD file defining its structure. --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>jaxb2-maven-plugin</artifactId> + <executions> + <execution> + <id>xjc</id> + <goals> + <goal>xjc</goal> + </goals> + </execution> + </executions> + <configuration> + <packageName>org.apache.rya.streams.querymanager.xml</packageName> + </configuration> + </plugin> + + <!-- Ensure the generated java source contains the lisence header. --> + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <configuration> + <header>${project.basedir}/src/license/header.txt</header> + </configuration> + <executions> + <execution> + <id>update-generated-source-headers</id> + <configuration> + <basedir>${project.build.directory}/generated-sources/jaxb</basedir> + <mapping> + <sun-jaxb.episode>XML_STYLE</sun-jaxb.episode> + </mapping> + </configuration> + <phase>process-sources</phase> + <goals> + <goal>format</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> @@ -71,4 +121,4 @@ under the License. </plugin> </plugins> </build> -</project> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/src/license/header.txt ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/src/license/header.txt b/extras/rya.streams/query-manager/src/license/header.txt new file mode 100644 index 0000000..90705e0 --- /dev/null +++ b/extras/rya.streams/query-manager/src/license/header.txt @@ -0,0 +1,16 @@ +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. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/src/main/config/configuration.xml ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/src/main/config/configuration.xml b/extras/rya.streams/query-manager/src/main/config/configuration.xml new file mode 100644 index 0000000..b78900e --- /dev/null +++ b/extras/rya.streams/query-manager/src/main/config/configuration.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +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. +--> +<queryManagerConfig> + <!-- A list of Query Change Log Sources. A source needs to be defined for + - every system that is used to manage Rya Streams Query Change Logs. + - The query manager will manage queries for all Rya instances whose + - change logs are stored within those sources. + --> + <queryChangeLogSources> + <queryChangeLogSource> + <kafka> + <hostname>[Kafka Broker Hostname]</hostname> + <port>[Kafka Broker Port]</port> + </kafka> + </queryChangeLogSource> + </queryChangeLogSources> + + <!-- This section defines performance related tuning values. Sensible + - default have been provided to simplify configuration. + --> + <performanceTunning> + <!-- Indicates how frequently the Query Change Logs that are defined + - in the sources section of this configuration file are polled for + - updates. This value effects how much time may pass between the + - state of a query changing and that change being represented by + - the execution engine. + --> + <queryChanngeLogDiscoveryPeriod> + <value>1</value> + <!-- Options: {MILLISECONDS, SECONDS, MINUTES} --> + <units>MINUTES</units> + </queryChanngeLogDiscoveryPeriod> + </performanceTunning> +</queryManagerConfig> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/src/main/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigUnmarshaller.java ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/src/main/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigUnmarshaller.java b/extras/rya.streams/query-manager/src/main/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigUnmarshaller.java new file mode 100644 index 0000000..834f0b9 --- /dev/null +++ b/extras/rya.streams/query-manager/src/main/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigUnmarshaller.java @@ -0,0 +1,78 @@ +/** + * 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.rya.streams.querymanager.xml; + +import static java.util.Objects.requireNonNull; + +import java.io.Reader; +import java.net.URL; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.xml.sax.SAXException; + +import edu.umd.cs.findbugs.annotations.DefaultAnnotation; +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Validates and unmarshalls XML into a {@link QueryManagerConfig} object. + */ +@DefaultAnnotation(NonNull.class) +public class QueryManagerConfigUnmarshaller { + + /** + * The path within the project's jar file where the XSD resides. + */ + private static final String XSD_PATH = "QueryManagerConfig.xsd"; + + /** + * Validates and unmarshalls XML into a {@link QueryManagerConfig} object. + * + * @param xmlReader - Reads the XML that will be unmarshalled. (not null) + * @return A {@link QueryManagerConfig} loaded with the XMLs values. + * @throws SAXException Could not load the schema the XML will be validated against. + * @throws JAXBException Could not unmarshal the XML into a POJO. + */ + public static QueryManagerConfig unmarshall(final Reader xmlReader) throws JAXBException, SAXException { + requireNonNull(xmlReader); + + // Get an input stream to the XSD file that is packaged inside of the jar. + final URL schemaURL = ClassLoader.getSystemResource(XSD_PATH); + if(schemaURL == null) { + throw new RuntimeException("The Class Loader was unable to find the following resource: " + XSD_PATH); + } + + // Get the schema for the object. + final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final Schema schema = sf.newSchema(schemaURL); + + // Configure the unmarhsaller to validate using the schema. + final JAXBContext context = JAXBContext.newInstance(QueryManagerConfig.class); + final Unmarshaller unmarshaller = context.createUnmarshaller(); + unmarshaller.setSchema(schema); + + // Perform the unmarshal. + return (QueryManagerConfig) unmarshaller.unmarshal(xmlReader); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/src/main/xsd/QueryManagerConfig.xsd ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/src/main/xsd/QueryManagerConfig.xsd b/extras/rya.streams/query-manager/src/main/xsd/QueryManagerConfig.xsd new file mode 100644 index 0000000..17d667f --- /dev/null +++ b/extras/rya.streams/query-manager/src/main/xsd/QueryManagerConfig.xsd @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- +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. +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <!-- Define the Query Manager's schema. --> + <xs:element name="queryManagerConfig"> + <xs:complexType> + <xs:sequence> + <xs:element name="queryChangeLogSources"> + <xs:complexType> + <xs:sequence> + <xs:element name="queryChangeLogSource" maxOccurs="unbounded"> + <xs:complexType> + <xs:choice> + <xs:element name="kafka" type="kafka"/> + </xs:choice> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="performanceTunning"> + <xs:complexType> + <xs:sequence> + <xs:element name="queryChanngeLogDiscoveryPeriod"> + <xs:complexType> + <xs:sequence> + <xs:element name="value" type="xs:positiveInteger"/> + <xs:element name="units" type="timeUnits"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + + <!-- Defines the time units that may be specified. --> + <xs:simpleType name="timeUnits" final="restriction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="MILLISECONDS"/> + <xs:enumeration value="SECONDS"/> + <xs:enumeration value="MINUTES"/> + </xs:restriction> + </xs:simpleType> + + <!-- Define what kafka connection information looks like. --> + <xs:complexType name="kafka"> + <xs:sequence> + <xs:element name="hostname" type="xs:string"/> + <xs:element name="port" type="tcpPort" /> + </xs:sequence> + </xs:complexType> + + <!-- Define the legal range for a TCP port. --> + <xs:simpleType name="tcpPort"> + <xs:restriction base="xs:int"> + <xs:minInclusive value="0"/> + <xs:maxInclusive value="65535"/> + </xs:restriction> + </xs:simpleType> +</xs:schema> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c1ccde80/extras/rya.streams/query-manager/src/test/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigMarshallerTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.streams/query-manager/src/test/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigMarshallerTest.java b/extras/rya.streams/query-manager/src/test/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigMarshallerTest.java new file mode 100644 index 0000000..bc8a040 --- /dev/null +++ b/extras/rya.streams/query-manager/src/test/java/org/apache/rya/streams/querymanager/xml/QueryManagerConfigMarshallerTest.java @@ -0,0 +1,78 @@ +/** + * 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.rya.streams.querymanager.xml; + +import static org.junit.Assert.assertNotNull; + +import java.io.StringReader; + +import javax.xml.bind.UnmarshalException; + +import org.junit.Test; + +/** + * Unit tests the methods of {@link QueryManagerConfigUnmarshaller}. + */ +public class QueryManagerConfigMarshallerTest { + + @Test + public void unmarshal_validXml() throws Exception { + final String xml = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<queryManagerConfig>\n" + + " <queryChangeLogSources>\n" + + " <queryChangeLogSource>\n" + + " <kafka>\n" + + " <hostname>localhost</hostname>\n" + + " <port>6</port>\n" + + " </kafka>\n" + + " </queryChangeLogSource>\n" + + " </queryChangeLogSources>\n" + + " <performanceTunning>\n" + + " <queryChanngeLogDiscoveryPeriod>\n" + + " <value>1</value>\n" + + " <units>MINUTES</units>\n" + + " </queryChanngeLogDiscoveryPeriod>\n" + + " </performanceTunning>\n" + + "</queryManagerConfig>"; + + + final QueryManagerConfig config = QueryManagerConfigUnmarshaller.unmarshall(new StringReader(xml)); + assertNotNull(config); + } + + @Test(expected = UnmarshalException.class) + public void unmarshal_invalidXml() throws Exception { + final String xml = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<queryManagerConfig>\n" + + " <queryChangeLogSources>\n" + + " <queryChangeLogSource>\n" + + " <kafka>\n" + + " <hostname>localhost</hostname>\n" + + " <port>6</port>\n" + + " </kafka>\n" + + " </queryChangeLogSource>\n" + + " </queryChangeLogSources>\n" + + "</queryManagerConfig>"; + + + QueryManagerConfigUnmarshaller.unmarshall(new StringReader(xml)); + } +} \ No newline at end of file
