You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2017/06/30 14:03:05 UTC
[17/27] brooklyn-server git commit: record underlying supplied
version in VersionedName
record underlying supplied version in VersionedName
support for persistence, and test
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/89fb1395
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/89fb1395
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/89fb1395
Branch: refs/heads/master
Commit: 89fb13955eef518f53e3c3330a20191c89a3cf2e
Parents: d8c03c8
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jun 22 13:17:32 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Jun 22 14:12:02 2017 +0100
----------------------------------------------------------------------
.../core/mgmt/rebind/MiscClassesRebindTest.java | 127 +++++++++++++++++++
...7-06-versionedname-entity-n7p20t5h4o.memento | 42 ++++++
.../brooklyn/util/osgi/VersionedName.java | 90 ++++++++++---
3 files changed, 239 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/89fb1395/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest.java
new file mode 100644
index 0000000..bbc40d0
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.brooklyn.core.mgmt.rebind;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Date;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Time;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.io.Files;
+
+/** Tests ability to rebind to previous version serialization state, for various classes;
+ * and utils to create such state (edit the config key value then run main method).
+ */
+public class MiscClassesRebindTest extends RebindTestFixtureWithApp {
+
+ private static final ConfigKey<Object> TEST_KEY = ConfigKeys.builder(Object.class).name("testKey").build();
+ private static final Logger log = LoggerFactory.getLogger(MiscClassesRebindTest.class);
+
+ /** Method to facilitate creation of memento files */
+ private void createMemento() throws Exception {
+ setUp();
+ origApp = super.createApp();
+
+ // edit this, run this class's main method, then use the log output for your test case
+ origApp.config().set(TEST_KEY, new VersionedName("foo", Version.parseVersion("1.0.0.foo")));
+
+
+ RebindTestUtils.stopPersistence(origApp);
+ String fn = mementoDir + File.separator + "entities" + File.separator + origApp.getApplicationId();
+ log.info("Persisted to "+fn);
+ String yyyyMM = Time.makeDateString(new Date(), "yyyy-MM");
+ log.info("Set up your tests by copying from the persistence dir "+mementoDir+"\n\n"+
+ "cp "+fn+" "+
+ "src/test/resources/"+getClass().getPackage().getName().replaceAll("\\.", "/")+"/"+
+ JavaClassNames.cleanSimpleClassName(this)+"-"+yyyyMM+"-entity-"+origApp.getApplicationId()+".memento\n");
+ String content = Streams.readFullyString(new FileInputStream(new File(fn)));
+ log.info("Or paste the following contents there:\n"+content);
+ log.info("Then add the apache comment header there, and write your test doing loadEntityMemento(\""+yyyyMM+"\", \""+origApp.getApplicationId()+"\")");
+ }
+
+ public static void main(String[] args) throws Exception {
+ new MiscClassesRebindTest().createMemento();
+ // halt to keep memento dir
+ Runtime.getRuntime().halt(0);
+ }
+
+
+ public TestApplication createApp() { /* no-op here for most tests */ return null; }
+
+ protected Entity loadEntityMemento(String label, String entityId) throws Exception {
+ String mementoResourceName = JavaClassNames.cleanSimpleClassName(this) + "-" + label + "-entity-" + entityId+".memento";
+ String memento = Streams.readFullyString(getClass().getResourceAsStream(mementoResourceName));
+
+ File persistedEntityFile = new File(mementoDir, Os.mergePaths("entities", entityId));
+ Files.write(memento.getBytes(), persistedEntityFile);
+
+ return newApp = rebind();
+ }
+
+ protected String getEntityMementoContent() throws InterruptedException, TimeoutException, FileNotFoundException {
+ RebindTestUtils.stopPersistence(newApp);
+ String fn = mementoDir + File.separator + "entities" + File.separator + newApp.getApplicationId();
+ return Streams.readFullyString(new FileInputStream(new File(fn)));
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T> T getTestKeyFromEntityMemento(String label, String entityId, Class<T> type) throws Exception {
+ Entity e = loadEntityMemento(label, entityId);
+ return (T) e.getConfig(TEST_KEY);
+ }
+
+
+ @Test
+ public void testVersionedName() throws Exception {
+ VersionedName vn = getTestKeyFromEntityMemento("2017-06-versionedname", "n7p20t5h4o", VersionedName.class);
+ Assert.assertEquals(vn, new VersionedName("foo", "1.0.0-foo"));
+ Assert.assertNotEquals(vn, new VersionedName("foo", "1.0.0.foo"));
+ Assert.assertTrue(vn.equalsOsgi(new VersionedName("foo", Version.parseVersion("1.0.0.foo"))));
+
+ String newEntityContent = getEntityMementoContent();
+ // log.info("New VN persistence is\n"+newEntityContent);
+ Asserts.assertStringContains(newEntityContent, "1.0.0-foo");
+ // phrases from original persisted state are changed
+ Asserts.assertStringDoesNotContain(newEntityContent, "<symbolicName>foo");
+ Asserts.assertStringDoesNotContain(newEntityContent, "<version>1.0.0");
+ Asserts.assertStringDoesNotContain(newEntityContent, "1.0.0.foo");
+ // they should now be this
+ Asserts.assertStringContains(newEntityContent, "<name>foo");
+ Asserts.assertStringContains(newEntityContent, "<v>1.0.0-foo");
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/89fb1395/core/src/test/resources/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest-2017-06-versionedname-entity-n7p20t5h4o.memento
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest-2017-06-versionedname-entity-n7p20t5h4o.memento b/core/src/test/resources/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest-2017-06-versionedname-entity-n7p20t5h4o.memento
new file mode 100644
index 0000000..0b98cbd
--- /dev/null
+++ b/core/src/test/resources/org/apache/brooklyn/core/mgmt/rebind/MiscClassesRebindTest-2017-06-versionedname-entity-n7p20t5h4o.memento
@@ -0,0 +1,42 @@
+<!--
+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.
+-->
+
+<entity>
+ <brooklynVersion>0.12.0-SNAPSHOT</brooklynVersion>
+ <type>org.apache.brooklyn.core.test.entity.TestApplicationNoEnrichersImpl</type>
+ <id>n7p20t5h4o</id>
+ <displayName>TestApplicationNoEnrichersImpl:n7p2</displayName>
+ <config>
+ <testKey>
+ <org.apache.brooklyn.util.osgi.VersionedName>
+ <symbolicName>foo</symbolicName>
+ <version>
+ <major>1</major>
+ <minor>0</minor>
+ <micro>0</micro>
+ <qualifier>foo</qualifier>
+ </version>
+ </org.apache.brooklyn.util.osgi.VersionedName>
+ </testKey>
+ </config>
+ <attributes>
+ <entity.id>n7p20t5h4o</entity.id>
+ <application.id>n7p20t5h4o</application.id>
+ </attributes>
+</entity>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/89fb1395/utils/common/src/main/java/org/apache/brooklyn/util/osgi/VersionedName.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/osgi/VersionedName.java b/utils/common/src/main/java/org/apache/brooklyn/util/osgi/VersionedName.java
index 5807904..e466d82 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/osgi/VersionedName.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/osgi/VersionedName.java
@@ -19,52 +19,93 @@ import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
-import com.google.common.base.Objects;
-import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
-/**
- * Versioned name of an OSGi bundle.
- * @author Ciprian Ciubotariu <ch...@gmx.net>
- */
+import com.google.common.base.Objects;
+
+/** Records a name (string) and version (string),
+ * with conveniences for pretty-printing and converting to OSGi format. */
public class VersionedName {
- private final String symbolicName;
- private final Version version;
+ private final String name;
+ private final String v;
+
+ @Deprecated // since 0.12.0 - remove along with version and readResolve in 0.13.0
+ private final String symbolicName = null;
+ @Deprecated // since 0.12.0
+ private final Version version = null;
+
+ private Object readResolve() {
+ if (symbolicName!=null || version!=null) {
+ // remove legacy fields, and convert to brooklyn recommended version in the process
+ // (might be slightly weird if bundles are persisted, but code will forgive that,
+ // and if types were persisted this will do the right thing)
+ return new VersionedName(symbolicName, BrooklynVersionSyntax.toGoodBrooklynVersion( version.toString() ));
+ }
+ return this;
+ }
+
public VersionedName(Bundle b) {
- this(b.getSymbolicName(), b.getVersion());
+ this(b.getSymbolicName(), b.getVersion().toString());
}
- public VersionedName(String symbolicName, @Nullable Version version) {
- this.symbolicName = checkNotNull(symbolicName, "symbolicName");
- this.version = version;
+ public VersionedName(String name, String v) {
+ this.name = checkNotNull(name, "name");
+ this.v = v;
+ }
+ public VersionedName(String name, @Nullable Version v) {
+ this.name = checkNotNull(name, "name").toString();
+ this.v = v==null ? null : v.toString();
}
+
@Override
public String toString() {
- return symbolicName + ":" + Strings.toString(version);
+ return name + ":" + v;
+ }
+
+ public String toOsgiString() {
+ return name + ":" + getOsgiVersion();
}
public boolean equals(String sn, String v) {
- return symbolicName.equals(sn) && (version == null && v == null || version != null && version.toString().equals(v));
+ return name.equals(sn) && Objects.equal(this.v, v);
+ // could also consider equal if the osgi mapping is equal (but for now we don't; if caller wants that, they should create Version)
+ // || (v!=null && Version.parseVersion(BrooklynVersionSyntax.toValidOsgiVersion(v)).equals(getOsgiVersion())));
}
public boolean equals(String sn, Version v) {
- return symbolicName.equals(sn) && (version == null && v == null || version != null && version.equals(v));
+ return name.equals(sn) && Objects.equal(getOsgiVersion(), v);
}
public String getSymbolicName() {
- return symbolicName;
+ return name;
}
+ private transient Version cachedOsgiVersion;
+ @Nullable
+ public Version getOsgiVersion() {
+ if (cachedOsgiVersion==null && v!=null) {
+ cachedOsgiVersion = v==null ? null : Version.parseVersion(BrooklynVersionSyntax.toValidOsgiVersion(v));
+ }
+ return cachedOsgiVersion;
+ }
+
+ @Nullable
+ public String getVersionString() {
+ return v;
+ }
+
+ @Deprecated /** @deprecated since 0.12.0 use {@link #getVersionString()} or {@link #getOsgiVersion()} */
public Version getVersion() {
- return version;
+ return getOsgiVersion();
}
@Override
public int hashCode() {
- return Objects.hashCode(symbolicName, version);
+ return Objects.hashCode(name, v);
}
@Override
@@ -73,14 +114,23 @@ public class VersionedName {
return false;
}
VersionedName o = (VersionedName) other;
- return Objects.equal(symbolicName, o.symbolicName) && Objects.equal(version, o.version);
+ return Objects.equal(name, o.name) && Objects.equal(v, o.v);
+ }
+
+ /** As {@link #equals(Object)} but accepting the argument as equal if versions are identical when injected to OSGi-valid versions */
+ public boolean equalsOsgi(Object other) {
+ if (!(other instanceof VersionedName)) {
+ return false;
+ }
+ VersionedName o = (VersionedName) other;
+ return Objects.equal(name, o.name) && Objects.equal(getOsgiVersion(), o.getOsgiVersion());
}
public static VersionedName fromString(String nameOptionalColonVersion) {
if (nameOptionalColonVersion==null) return null;
int colon = nameOptionalColonVersion.indexOf(':');
if (colon<0) throw new IllegalArgumentException("Versioned name '"+nameOptionalColonVersion+"' must be of form 'name:version'");
- return new VersionedName(nameOptionalColonVersion.substring(0, colon), Version.parseVersion(nameOptionalColonVersion.substring(colon+1)));
+ return new VersionedName(nameOptionalColonVersion.substring(0, colon), nameOptionalColonVersion.substring(colon+1));
}
}