The task was so trivial I haven't checked for other implementations. I will for sure turn to Felix in case my requirements become more complicated than that.
On Mon, 2 Jul 2018 at 19:57, Julian Sedding <[email protected]> wrote: > Hi Francesco > > Have you considered using the MetaTypeReader from Felix' MetyType > implementation[0]? I've used it before and found it easy enough to > use. > > It's only a test dependency, and you don't need to worry about your > implementation being in sync with the spec/Felix' implementation. > > Regards > Julian > > [0] > https://github.com/apache/felix/blob/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java > > On Mon, Jul 2, 2018 at 4:57 PM, <[email protected]> wrote: > > Author: frm > > Date: Mon Jul 2 14:57:25 2018 > > New Revision: 1834852 > > > > URL: http://svn.apache.org/viewvc?rev=1834852&view=rev > > Log: > > OAK-6770 - Test the metatype information descriptors > > > > Added: > > > > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java > (with props) > > Modified: > > > > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreFactoryTest.java > > > > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreMonitorServiceTest.java > > > > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreServiceTest.java > > > > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/StandbyStoreServiceTest.java > > > > Added: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java > > URL: > http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java?rev=1834852&view=auto > > > ============================================================================== > > --- > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java > (added) > > +++ > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java > Mon Jul 2 14:57:25 2018 > > @@ -0,0 +1,267 @@ > > +/* > > + * 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.jackrabbit.oak.segment.osgi; > > + > > +import java.io.InputStream; > > +import java.util.HashSet; > > +import java.util.Set; > > + > > +import javax.xml.parsers.DocumentBuilder; > > +import javax.xml.parsers.DocumentBuilderFactory; > > + > > +import org.w3c.dom.Document; > > +import org.w3c.dom.Element; > > +import org.w3c.dom.NodeList; > > + > > +class MetatypeInformation { > > + > > + static MetatypeInformation open(InputStream stream) throws > Exception { > > + DocumentBuilderFactory factory = > DocumentBuilderFactory.newInstance(); > > + DocumentBuilder builder = factory.newDocumentBuilder(); > > + Document document = builder.parse(stream); > > + return new MetatypeInformation(document.getDocumentElement()); > > + } > > + > > + private static boolean hasAttribute(Element element, String name, > String value) { > > + return element.hasAttribute(name) && > element.getAttribute(name).equals(value); > > + } > > + > > + private final Element root; > > + > > + private MetatypeInformation(Element root) { > > + this.root = root; > > + } > > + > > + ObjectClassDefinition getObjectClassDefinition(String id) { > > + return new ObjectClassDefinition(id); > > + } > > + > > + class ObjectClassDefinition { > > + > > + private final String id; > > + > > + private ObjectClassDefinition(String id) { > > + this.id = id; > > + } > > + > > + HasAttributeDefinition hasAttributeDefinition(String id) { > > + return new HasAttributeDefinition(this.id, id); > > + } > > + > > + } > > + > > + class HasAttributeDefinition { > > + > > + private final String ocd; > > + > > + private final String id; > > + > > + private String type; > > + > > + private String defaultValue; > > + > > + private String cardinality; > > + > > + private String[] options; > > + > > + private HasAttributeDefinition(String ocd, String id) { > > + this.ocd = ocd; > > + this.id = id; > > + } > > + > > + HasAttributeDefinition withStringType() { > > + this.type = "String"; > > + return this; > > + } > > + > > + HasAttributeDefinition withLongType() { > > + this.type = "Long"; > > + return this; > > + } > > + > > + HasAttributeDefinition withDoubleType() { > > + this.type = "Double"; > > + return this; > > + } > > + > > + HasAttributeDefinition withFloatType() { > > + this.type = "Float"; > > + return this; > > + } > > + > > + HasAttributeDefinition withIntegerType() { > > + this.type = "Integer"; > > + return this; > > + } > > + > > + HasAttributeDefinition withByteType() { > > + this.type = "Byte"; > > + return this; > > + } > > + > > + HasAttributeDefinition withCharType() { > > + this.type = "Char"; > > + return this; > > + } > > + > > + HasAttributeDefinition withBooleanType() { > > + this.type = "Boolean"; > > + return this; > > + } > > + > > + HasAttributeDefinition withShortType() { > > + this.type = "Short"; > > + return this; > > + } > > + > > + HasAttributeDefinition withDefaultValue(String defaultValue) { > > + this.defaultValue = defaultValue; > > + return this; > > + } > > + > > + HasAttributeDefinition withCardinality(String cardinality) { > > + this.cardinality = cardinality; > > + return this; > > + } > > + > > + HasAttributeDefinition withOptions(String... options) { > > + this.options = options; > > + return this; > > + } > > + > > + boolean check() { > > + NodeList ocds = root.getElementsByTagName("OCD"); > > + for (int i = 0; i < ocds.getLength(); i++) { > > + Element ocd = (Element) ocds.item(i); > > + if (hasAttribute(ocd, "id", this.ocd)) { > > + return checkOCD(ocd); > > + } > > + } > > + return false; > > + } > > + > > + private boolean checkOCD(Element ocd) { > > + NodeList ads = ocd.getElementsByTagName("AD"); > > + for (int i = 0; i < ads.getLength(); i++) { > > + Element ad = (Element) ads.item(i); > > + if (hasAttribute(ad, "id", id)) { > > + return checkAD(ad); > > + } > > + } > > + return false; > > + } > > + > > + private boolean checkAD(Element ad) { > > + if (type != null && !hasAttribute(ad, "type", type)) { > > + return false; > > + } > > + if (defaultValue != null && !hasAttribute(ad, "default", > defaultValue)) { > > + return false; > > + } > > + if (cardinality != null && !hasAttribute(ad, "cardinality", > cardinality)) { > > + return false; > > + } > > + if (options != null) { > > + Set<String> optionValues = new HashSet<>(); > > + > > + NodeList optionElements = > ad.getElementsByTagName("Option"); > > + for (int i = 0; i < optionElements.getLength(); i++) { > > + Element optionElement = (Element) > optionElements.item(i); > > + > optionValues.add(optionElement.getAttribute("value")); > > + } > > + > > + if (options.length != optionValues.size()) { > > + return false; > > + } > > + > > + for (String option : options) { > > + if (!optionValues.contains(option)) { > > + return false; > > + } > > + } > > + } > > + return true; > > + } > > + > > + } > > + > > + HasDesignate hasDesignate() { > > + return new HasDesignate(); > > + } > > + > > + class HasDesignate { > > + > > + private String pid; > > + > > + private String factoryPid; > > + > > + private String reference; > > + > > + private HasDesignate() { > > + // Prevent instantiation outside of this class. > > + } > > + > > + HasDesignate withPid(String pid) { > > + this.pid = pid; > > + return this; > > + } > > + > > + HasDesignate withFactoryPid(String factoryPid) { > > + this.factoryPid = factoryPid; > > + return this; > > + } > > + > > + HasDesignate withReference(String reference) { > > + this.reference = reference; > > + return this; > > + } > > + > > + boolean check() { > > + NodeList designates = > root.getElementsByTagName("Designate"); > > + for (int i = 0; i < designates.getLength(); i++) { > > + if (checkDesignate((Element) designates.item(i))) { > > + return true; > > + } > > + } > > + return false; > > + } > > + > > + private boolean checkDesignate(Element element) { > > + if (pid != null && !hasAttribute(element, "pid", pid)) { > > + return false; > > + } > > + if (factoryPid != null && !hasAttribute(element, > "factoryPid", factoryPid)) { > > + return false; > > + } > > + if (reference != null) { > > + NodeList objects = > element.getElementsByTagName("Object"); > > + for (int i = 0; i < objects.getLength(); i++) { > > + if (hasAttribute((Element) objects.item(i), > "ocdref", reference)) { > > + return true; > > + } > > + } > > + return false; > > + } > > + return true; > > + } > > + > > + } > > + > > +} > > > > Propchange: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/MetatypeInformation.java > > > ------------------------------------------------------------------------------ > > svn:eol-style = native > > > > Modified: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreFactoryTest.java > > URL: > http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreFactoryTest.java?rev=1834852&r1=1834851&r2=1834852&view=diff > > > ============================================================================== > > --- > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreFactoryTest.java > (original) > > +++ > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreFactoryTest.java > Mon Jul 2 14:57:25 2018 > > @@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.segmen > > > > import static org.junit.Assert.assertTrue; > > > > +import > org.apache.jackrabbit.oak.segment.osgi.MetatypeInformation.ObjectClassDefinition; > > import org.junit.Test; > > > > public class SegmentNodeStoreFactoryTest { > > @@ -69,6 +70,37 @@ public class SegmentNodeStoreFactoryTest > > .withBind("bindStatisticsProvider") > > .withUnbind("unbindStatisticsProvider") > > .check()); > > + } > > + > > + @Test > > + public void testMetatypeInformation() throws Exception { > > + MetatypeInformation mi = > MetatypeInformation.open(getClass().getResourceAsStream("/OSGI-INF/metatype/org.apache.jackrabbit.oak.segment.SegmentNodeStoreFactory.xml")); > > + assertTrue(mi.hasDesignate() > > + > .withPid("org.apache.jackrabbit.oak.segment.SegmentNodeStoreFactory") > > + > .withFactoryPid("org.apache.jackrabbit.oak.segment.SegmentNodeStoreFactory") > > + > .withReference("org.apache.jackrabbit.oak.segment.SegmentNodeStoreFactory") > > + .check()); > > > > + ObjectClassDefinition ocd = > mi.getObjectClassDefinition("org.apache.jackrabbit.oak.segment.SegmentNodeStoreFactory"); > > + assertTrue(ocd.hasAttributeDefinition("role") > > + .withStringType() > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("customBlobStore") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("customBlobStore") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("customSegmentStore") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("registerDescriptors") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > } > > + > > } > > > > Modified: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreMonitorServiceTest.java > > URL: > http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreMonitorServiceTest.java?rev=1834852&r1=1834851&r2=1834852&view=diff > > > ============================================================================== > > --- > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreMonitorServiceTest.java > (original) > > +++ > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreMonitorServiceTest.java > Mon Jul 2 14:57:25 2018 > > @@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.segmen > > > > import static org.junit.Assert.assertTrue; > > > > +import > org.apache.jackrabbit.oak.segment.osgi.MetatypeInformation.ObjectClassDefinition; > > import org.junit.Test; > > > > public class SegmentNodeStoreMonitorServiceTest { > > @@ -41,4 +42,20 @@ public class SegmentNodeStoreMonitorServ > > .withUnbind("unbindSnsStatsMBean") > > .check()); > > } > > + > > + @Test > > + public void testMetatypeInformation() throws Exception { > > + MetatypeInformation mi = > MetatypeInformation.open(getClass().getResourceAsStream("/OSGI-INF/metatype/org.apache.jackrabbit.oak.segment.SegmentNodeStoreMonitorService.xml")); > > + assertTrue(mi.hasDesignate() > > + > .withPid("org.apache.jackrabbit.oak.segment.SegmentNodeStoreMonitorService") > > + > .withReference("org.apache.jackrabbit.oak.segment.SegmentNodeStoreMonitorService") > > + .check()); > > + > > + ObjectClassDefinition ocd = > mi.getObjectClassDefinition("org.apache.jackrabbit.oak.segment.SegmentNodeStoreMonitorService"); > > + > assertTrue(ocd.hasAttributeDefinition("commitsTrackerWriterGroups") > > + .withStringType() > > + .withCardinality("2147483647") > > + .check()); > > + > > + } > > } > > > > Modified: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreServiceTest.java > > URL: > http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreServiceTest.java?rev=1834852&r1=1834851&r2=1834852&view=diff > > > ============================================================================== > > --- > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreServiceTest.java > (original) > > +++ > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/SegmentNodeStoreServiceTest.java > Mon Jul 2 14:57:25 2018 > > @@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.segmen > > > > import static org.junit.Assert.assertTrue; > > > > +import > org.apache.jackrabbit.oak.segment.osgi.MetatypeInformation.ObjectClassDefinition; > > import org.junit.Test; > > > > public class SegmentNodeStoreServiceTest { > > @@ -141,4 +142,105 @@ public class SegmentNodeStoreServiceTest > > .withUnbind("unbindStatisticsProvider") > > .check()); > > } > > + > > + @Test > > + public void testMetatypeInformation() throws Exception { > > + MetatypeInformation mi = > MetatypeInformation.open(getClass().getResourceAsStream("/OSGI-INF/metatype/org.apache.jackrabbit.oak.segment.SegmentNodeStoreService.xml")); > > + assertTrue(mi.hasDesignate() > > + > .withPid("org.apache.jackrabbit.oak.segment.SegmentNodeStoreService") > > + > .withReference("org.apache.jackrabbit.oak.segment.SegmentNodeStoreService") > > + .check()); > > + > > + ObjectClassDefinition ocd = > mi.getObjectClassDefinition("org.apache.jackrabbit.oak.segment.SegmentNodeStoreService"); > > + assertTrue(ocd.hasAttributeDefinition("repository.home") > > + .withStringType() > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("tarmk.mode") > > + .withStringType() > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("tarmk.size") > > + .withIntegerType() > > + .withDefaultValue("256") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("segmentCache.size") > > + .withIntegerType() > > + .withDefaultValue("256") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("stringCache.size") > > + .withIntegerType() > > + .withDefaultValue("256") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("templateCache.size") > > + .withIntegerType() > > + .withDefaultValue("64") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("stringDeduplicationCache.size") > > + .withIntegerType() > > + .withDefaultValue("15000") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("templateDeduplicationCache.size") > > + .withIntegerType() > > + .withDefaultValue("3000") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("nodeDeduplicationCache.size") > > + .withIntegerType() > > + .withDefaultValue("1048576") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("pauseCompaction") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("compaction.retryCount") > > + .withIntegerType() > > + .withDefaultValue("5") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("compaction.force.timeout") > > + .withIntegerType() > > + .withDefaultValue("60") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("compaction.sizeDeltaEstimation") > > + .withLongType() > > + .withDefaultValue("1073741824") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("compaction.disableEstimation") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("compaction.retainedGenerations") > > + .withIntegerType() > > + .withDefaultValue("2") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("compaction.memoryThreshold") > > + .withIntegerType() > > + .withDefaultValue("15") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("compaction.progressLog") > > + .withLongType() > > + .withDefaultValue("-1") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("standby") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("customBlobStore") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("customSegmentStore") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("repository.backup.dir") > > + .withStringType() > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("blobGcMaxAgeInSecs") > > + .withLongType() > > + .withDefaultValue("86400") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("blobTrackSnapshotIntervalInSecs") > > + .withLongType() > > + .withDefaultValue("43200") > > + .check()); > > + } > > + > > } > > > > Modified: > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/StandbyStoreServiceTest.java > > URL: > http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/StandbyStoreServiceTest.java?rev=1834852&r1=1834851&r2=1834852&view=diff > > > ============================================================================== > > --- > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/StandbyStoreServiceTest.java > (original) > > +++ > jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/osgi/StandbyStoreServiceTest.java > Mon Jul 2 14:57:25 2018 > > @@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.segmen > > > > import static org.junit.Assert.assertTrue; > > > > +import > org.apache.jackrabbit.oak.segment.osgi.MetatypeInformation.ObjectClassDefinition; > > import org.junit.Test; > > > > public class StandbyStoreServiceTest { > > @@ -75,4 +76,52 @@ public class StandbyStoreServiceTest { > > .check()); > > } > > > > + @Test > > + public void testMetatypeInformation() throws Exception { > > + MetatypeInformation mi = > MetatypeInformation.open(getClass().getResourceAsStream("/OSGI-INF/metatype/org.apache.jackrabbit.oak.segment.standby.store.StandbyStoreService.xml")); > > + assertTrue(mi.hasDesignate() > > + > .withPid("org.apache.jackrabbit.oak.segment.standby.store.StandbyStoreService") > > + > .withReference("org.apache.jackrabbit.oak.segment.standby.store.StandbyStoreService") > > + .check()); > > + > > + ObjectClassDefinition ocd = > mi.getObjectClassDefinition("org.apache.jackrabbit.oak.segment.standby.store.StandbyStoreService"); > > + > assertTrue(ocd.hasAttributeDefinition("org.apache.sling.installer.configuration.persist") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("mode") > > + .withStringType() > > + .withDefaultValue("primary") > > + .withOptions("primary", "standby") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("port") > > + .withIntegerType() > > + .withDefaultValue("8023") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("primary.host") > > + .withStringType() > > + .withDefaultValue("127.0.0.1") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("interval") > > + .withIntegerType() > > + .withDefaultValue("5") > > + .check()); > > + > assertTrue(ocd.hasAttributeDefinition("primary.allowed-client-ip-ranges") > > + .withStringType() > > + .withCardinality("2147483647") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("secure") > > + .withBooleanType() > > + .withDefaultValue("false") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("standby.readtimeout") > > + .withIntegerType() > > + .withDefaultValue("60000") > > + .check()); > > + assertTrue(ocd.hasAttributeDefinition("standby.autoclean") > > + .withBooleanType() > > + .withDefaultValue("true") > > + .check()); > > + } > > + > > } > > > > >
