This is an automated email from the ASF dual-hosted git repository. jinmeiliao pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
commit 93ed36f9c9248261fdb7817da4e51f49849f876c Author: Jinmei Liao <[email protected]> AuthorDate: Wed Dec 5 15:15:07 2018 -0800 GEODE-5971: create region still needs to fetch xml from server to get get extensions xml --- .gitignore | 1 - .../integrationTest/resources/assembly_content.txt | 7 +- .../InternalConfigurationPersistenceService.java | 4 + .../apache/geode/internal/config/JAXBService.java | 22 +- .../internal/cli/commands/CreateRegionCommand.java | 23 ++ .../cli/functions/RegionCreateFunction.java | 15 +- .../geode/internal/config/JAXBServiceTest.java | 22 ++ .../LuceneClusterConfigurationDUnitTest.java | 4 +- .../cli/functions/LuceneCreateIndexFunction.java | 4 +- .../lucene/management/configuration/Index.java | 237 +++++++++++++++++++++ .../management/configuration/package-info.java | 22 ++ .../sanctioned-geode-lucene-serializables.txt | 1 + 12 files changed, 346 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 1525f4a..47d635b 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ out/ *.orig geode-pulse/screenshots/ /jpf.properties -geode-assembly/assembly_content.txt .git-together bin/ diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt index f216ab3..2844d1e 100644 --- a/geode-assembly/src/integrationTest/resources/assembly_content.txt +++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt @@ -388,6 +388,11 @@ javadoc/org/apache/geode/cache/lucene/LuceneServiceProvider.html javadoc/org/apache/geode/cache/lucene/PageableLuceneQueryResults.html javadoc/org/apache/geode/cache/lucene/management/LuceneIndexMetrics.html javadoc/org/apache/geode/cache/lucene/management/LuceneServiceMXBean.html +javadoc/org/apache/geode/cache/lucene/management/configuration/Index.Field.html +javadoc/org/apache/geode/cache/lucene/management/configuration/Index.html +javadoc/org/apache/geode/cache/lucene/management/configuration/package-frame.html +javadoc/org/apache/geode/cache/lucene/management/configuration/package-summary.html +javadoc/org/apache/geode/cache/lucene/management/configuration/package-tree.html javadoc/org/apache/geode/cache/lucene/management/package-frame.html javadoc/org/apache/geode/cache/lucene/management/package-summary.html javadoc/org/apache/geode/cache/lucene/management/package-tree.html @@ -957,4 +962,4 @@ tools/Modules/Apache_Geode_Modules-0.0.0-AppServer.zip tools/Modules/Apache_Geode_Modules-0.0.0-Tomcat.zip tools/Modules/Apache_Geode_Modules-0.0.0-tcServer.zip tools/Modules/Apache_Geode_Modules-0.0.0-tcServer30.zip -tools/Pulse/geode-pulse-0.0.0.war \ No newline at end of file +tools/Pulse/geode-pulse-0.0.0.war diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java index c86a969..f9f1169 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalConfigurationPersistenceService.java @@ -156,6 +156,10 @@ public class InternalConfigurationPersistenceService implements ConfigurationPer jaxbService = new JAXBService(CacheConfig.class); } + public JAXBService getJaxbService() { + return jaxbService; + } + public InternalConfigurationPersistenceService(InternalCache cache, Class<?>... xsdClasses) throws IOException { this.cache = cache; diff --git a/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java b/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java index 221e154..3ceb644 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java +++ b/geode-core/src/main/java/org/apache/geode/internal/config/JAXBService.java @@ -44,6 +44,7 @@ import org.apache.geode.internal.ClassPathLoader; public class JAXBService { Marshaller marshaller; Unmarshaller unmarshaller; + NameSpaceFilter nameSpaceFilter; public JAXBService(Class<?>... xsdRootClasses) { try { @@ -63,6 +64,10 @@ public class JAXBService { }).filter(Objects::nonNull).collect(Collectors.joining(" ")); marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemas); + // use a custom Filter so that we can unmarshall older namespace or no namespace xml + XMLReader reader = XMLReaderFactory.createXMLReader(); + nameSpaceFilter = new NameSpaceFilter(); + nameSpaceFilter.setParent(reader); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } @@ -99,19 +104,20 @@ public class JAXBService { public <T> T unMarshall(String xml) { try { - InputSource is = new InputSource(new StringReader(xml)); - XMLReader reader = XMLReaderFactory.createXMLReader(); - - // use a custom Filter so that we can unmarshall older namespace or no namespace xml - NameSpaceFilter filter = new NameSpaceFilter(); - filter.setParent(reader); - SAXSource source = new SAXSource(filter, is); - + SAXSource source = new SAXSource(nameSpaceFilter, new InputSource(new StringReader(xml))); return (T) unmarshaller.unmarshal(source); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } + public <T> T unMarshall(String xml, Class<T> klass) { + try { + SAXSource source = new SAXSource(nameSpaceFilter, new InputSource(new StringReader(xml))); + return unmarshaller.unmarshal(source, klass).getValue(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java index 4686f01..888287d 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateRegionCommand.java @@ -40,9 +40,11 @@ import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.configuration.CacheConfig; +import org.apache.geode.cache.configuration.CacheElement; import org.apache.geode.cache.configuration.RegionConfig; import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.logging.LogService; import org.apache.geode.management.DistributedRegionMXBean; @@ -442,9 +444,30 @@ public class CreateRegionCommand extends SingleGfshCommand { RegionCreateFunction.INSTANCE, functionArgs, membersToCreateRegionOn); ResultModel resultModel = ResultModel.createMemberStatusResult(regionCreateResults); + InternalConfigurationPersistenceService service = + (InternalConfigurationPersistenceService) getConfigurationPersistenceService(); + + if (service == null) { + return resultModel; + } + + // otherwise, prepare the regionConfig for persistence if (resultModel.isSuccessful()) { verifyDistributedRegionMbean(cache, regionPath); RegionConfig config = (new RegionConfigFactory()).generate(functionArgs); + // the following is a temporary solution before lucene make the change to create region first + // before creating the lucene index. + // GEODE-3924 + // we will need to get the xml returned from the server to find out any custom xml nested + // inside the region + String regionXml = (String) regionCreateResults.stream() + .filter(CliFunctionResult::isSuccessful) + .findFirst().get().getResultObject(); + RegionConfig regionConfigFromServer = + service.getJaxbService().unMarshall(regionXml, RegionConfig.class); + List<CacheElement> extensions = regionConfigFromServer.getCustomRegionElements(); + config.getCustomRegionElements().addAll(extensions); + resultModel.setConfigObject(new CreateRegionResultConfig(config, functionArgs.getRegionPath())); } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java index 9dfa16d..26ed5a4 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/RegionCreateFunction.java @@ -44,12 +44,14 @@ import org.apache.geode.compression.Compressor; import org.apache.geode.internal.ClassPathLoader; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.execute.InternalFunction; +import org.apache.geode.internal.cache.xmlcache.CacheXml; import org.apache.geode.internal.logging.LogService; import org.apache.geode.management.internal.cli.CliUtil; import org.apache.geode.management.internal.cli.commands.RegionCommandsUtils; import org.apache.geode.management.internal.cli.domain.ClassName; import org.apache.geode.management.internal.cli.i18n.CliStrings; import org.apache.geode.management.internal.cli.util.RegionPath; +import org.apache.geode.management.internal.configuration.domain.XmlEntity; /** * @@ -93,9 +95,9 @@ public class RegionCreateFunction implements InternalFunction { try { Region<?, ?> createdRegion = createRegion(cache, regionCreateArgs); - + XmlEntity xmlEntity = getXmlEntityForRegion(createdRegion); resultSender - .lastResult(new CliFunctionResult(memberNameOrId, CliFunctionResult.StatusState.OK, + .lastResult(new CliFunctionResult(memberNameOrId, xmlEntity.getXmlDefinition(), CliStrings.format(CliStrings.CREATE_REGION__MSG__REGION_0_CREATED_ON_1, createdRegion.getFullPath(), memberNameOrId))); } catch (IllegalStateException e) { @@ -124,6 +126,15 @@ public class RegionCreateFunction implements InternalFunction { } } + private XmlEntity getXmlEntityForRegion(Region<?, ?> region) { + Region<?, ?> curRegion = region; + while (curRegion != null && curRegion.getParentRegion() != null) { + curRegion = curRegion.getParentRegion(); + } + + return new XmlEntity(CacheXml.REGION, "name", curRegion.getName()); + } + private CliFunctionResult handleException(final String memberNameOrId, final String exceptionMsg, final Exception e) { if (e != null && logger.isDebugEnabled()) { diff --git a/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java b/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java index 67f0807..c39866a 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/config/JAXBServiceTest.java @@ -137,6 +137,28 @@ public class JAXBServiceTest { } @Test + public void unmarshallPartialElement() { + String xml = "<region name=\"one\">\n" + + " <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n" + + " </region>"; + + RegionConfig config = service2.unMarshall(xml, RegionConfig.class); + assertThat(config.getName()).isEqualTo("one"); + } + + @Test + public void unmarshallAnyElement() { + String xml = "<region name=\"one\">\n" + + " <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n" + + " <custom:any xmlns:custom=\"http://geode.apache.org/schema/custom\" id=\"any\"/>" + + " </region>"; + + RegionConfig config = service2.unMarshall(xml, RegionConfig.class); + assertThat(config.getName()).isEqualTo("one"); + assertThat(config.getCustomRegionElements()).hasSize(1); + } + + @Test public void unmarshallIgnoresUnknownProperties() { // say xml has a type attribute that is removed in the new version String existingXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" diff --git a/geode-lucene/src/distributedTest/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java b/geode-lucene/src/distributedTest/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java index 98c7169..e05b15a 100644 --- a/geode-lucene/src/distributedTest/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java +++ b/geode-lucene/src/distributedTest/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java @@ -267,10 +267,10 @@ public class LuceneClusterConfigurationDUnitTest { Configuration config = sc.getConfiguration(ConfigurationPersistenceService.CLUSTER_CONFIG); String xmlContent = config.getCacheXmlContent(); String luceneIndex0Config = "<" + LuceneXmlConstants.PREFIX + ":" + LuceneXmlConstants.INDEX - + " xmlns:lucene=\"" + LuceneXmlConstants.NAMESPACE + "\" " + LuceneXmlConstants.NAME + + " " + LuceneXmlConstants.NAME + "=\"" + INDEX_NAME + "0" + "\">"; String luceneIndex1Config = "<" + LuceneXmlConstants.PREFIX + ":" + LuceneXmlConstants.INDEX - + " xmlns:lucene=\"" + LuceneXmlConstants.NAMESPACE + "\" " + LuceneXmlConstants.NAME + + " " + LuceneXmlConstants.NAME + "=\"" + INDEX_NAME + "1" + "\">"; if (verifyIndexesExist) { assertThat(xmlContent).contains(luceneIndex0Config); diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneCreateIndexFunction.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneCreateIndexFunction.java index 4c2c3cd..e789ec0 100644 --- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneCreateIndexFunction.java +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneCreateIndexFunction.java @@ -103,7 +103,7 @@ public class LuceneCreateIndexFunction implements InternalFunction { if (LuceneServiceImpl.LUCENE_REINDEX) { indexFactory.create(indexName, regionPath, true); if (cache.getRegion(regionPath) != null) { - xmlEntity = getXmlEntity(indexName, regionPath); + xmlEntity = getXmlEntity(regionPath); } } else { indexFactory.create(indexName, regionPath, false); @@ -117,7 +117,7 @@ public class LuceneCreateIndexFunction implements InternalFunction { } } - protected XmlEntity getXmlEntity(String indexName, String regionPath) { + protected XmlEntity getXmlEntity(String regionPath) { String regionName = StringUtils.stripStart(regionPath, "/"); return new XmlEntity(CacheXml.REGION, "name", regionName); } diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/Index.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/Index.java new file mode 100644 index 0000000..b87ed42 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/Index.java @@ -0,0 +1,237 @@ + +/* + * 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.geode.cache.lucene.management.configuration; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.apache.geode.cache.configuration.CacheElement; +import org.apache.geode.cache.configuration.DeclarableType; +import org.apache.geode.cache.configuration.XSDRootElement; + + +/** + * <p> + * Java class for anonymous complex type. + * + * <p> + * The following schema fragment specifies the expected content contained within this class. + * + * <pre> + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + * <sequence> + * <element name="field" maxOccurs="unbounded"> + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> + * <attribute name="analyzer" type="{http://www.w3.org/2001/XMLSchema}string" /> + * </restriction> + * </complexContent> + * </complexType> + * </element> + * <element name="serializer" type="{http://geode.apache.org/schema/cache}declarable-type" minOccurs="0"/> + * </sequence> + * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> + * </restriction> + * </complexContent> + * </complexType> + * </pre> + * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "field", + "serializer" +}) +@XmlRootElement(name = "index", namespace = "http://geode.apache.org/schema/lucene") +@XSDRootElement(namespace = "http://geode.apache.org/schema/lucene", + schemaLocation = "http://geode.apache.org/schema/lucene/lucene-1.0.xsd") +public class Index implements CacheElement { + @XmlElement(namespace = "http://geode.apache.org/schema/lucene", required = true) + protected List<Index.Field> field; + @XmlElement(namespace = "http://geode.apache.org/schema/lucene") + protected DeclarableType serializer; + @XmlAttribute(name = "name") + protected String name; + + /** + * Gets the value of the field property. + * + * <p> + * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a <CODE>set</CODE> method for the field property. + * + * <p> + * For example, to add a new item, do as follows: + * + * <pre> + * getField().add(newItem); + * </pre> + * + * + * <p> + * Objects of the following type(s) are allowed in the list + * {@link Index.Field } + * + * + */ + public List<Index.Field> getField() { + if (field == null) { + field = new ArrayList<Index.Field>(); + } + return this.field; + } + + /** + * Gets the value of the serializer property. + * + * possible object is + * {@link DeclarableType } + * + */ + public DeclarableType getSerializer() { + return serializer; + } + + /** + * Sets the value of the serializer property. + * + * allowed object is + * {@link DeclarableType } + * + */ + public void setSerializer(DeclarableType value) { + this.serializer = value; + } + + /** + * Gets the value of the name property. + * + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + @Override + public String getId() { + return getName(); + } + + + /** + * <p> + * Java class for anonymous complex type. + * + * <p> + * The following schema fragment specifies the expected content contained within this class. + * + * <pre> + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> + * <attribute name="analyzer" type="{http://www.w3.org/2001/XMLSchema}string" /> + * </restriction> + * </complexContent> + * </complexType> + * </pre> + * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "") + public static class Field { + + @XmlAttribute(name = "name") + protected String name; + @XmlAttribute(name = "analyzer") + protected String analyzer; + + /** + * Gets the value of the name property. + * + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the analyzer property. + * + * possible object is + * {@link String } + * + */ + public String getAnalyzer() { + return analyzer; + } + + /** + * Sets the value of the analyzer property. + * + * allowed object is + * {@link String } + * + */ + public void setAnalyzer(String value) { + this.analyzer = value; + } + + } + +} diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/package-info.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/package-info.java new file mode 100644 index 0000000..2d2c0f1 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/management/configuration/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ + +@XmlSchema(namespace = "http://geode.apache.org/schema/lucene", + xmlns = {@XmlNs(prefix = "lucene", namespaceURI = "http://geode.apache.org/schema/lucene")}, + elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) +package org.apache.geode.cache.lucene.management.configuration; + +import javax.xml.bind.annotation.XmlNs; +import javax.xml.bind.annotation.XmlSchema; diff --git a/geode-lucene/src/main/resources/org/apache/geode/internal/sanctioned-geode-lucene-serializables.txt b/geode-lucene/src/main/resources/org/apache/geode/internal/sanctioned-geode-lucene-serializables.txt index 4f0a2b2..491a993 100755 --- a/geode-lucene/src/main/resources/org/apache/geode/internal/sanctioned-geode-lucene-serializables.txt +++ b/geode-lucene/src/main/resources/org/apache/geode/internal/sanctioned-geode-lucene-serializables.txt @@ -2,6 +2,7 @@ org/apache/geode/cache/lucene/LuceneIndexDestroyedException,false,indexName:java org/apache/geode/cache/lucene/LuceneIndexExistsException,false,indexName:java/lang/String,regionPath:java/lang/String org/apache/geode/cache/lucene/LuceneIndexNotFoundException,false,indexName:java/lang/String,regionPath:java/lang/String org/apache/geode/cache/lucene/LuceneQueryException,false +org/apache/geode/cache/lucene/management/configuration/Index,false,field:java/util/List,name:java/lang/String,serializer:org/apache/geode/cache/configuration/DeclarableType org/apache/geode/cache/lucene/internal/LuceneIndexCreationInProgressException,false org/apache/geode/cache/lucene/internal/cli/LuceneDestroyIndexInfo,false,definedDestroyOnly:boolean org/apache/geode/cache/lucene/internal/cli/LuceneFunctionSerializable,false,indexName:java/lang/String,regionPath:java/lang/String
