[ https://issues.apache.org/jira/browse/GEODE-4039?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16297457#comment-16297457 ]
ASF GitHub Bot commented on GEODE-4039: --------------------------------------- PivotalSarge closed pull request #38: GEODE-4039: Add serialization example. URL: https://github.com/apache/geode-examples/pull/38 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/README.md b/README.md index 501635e..d74e0b3 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,9 @@ tutorial. ### Intermediate -* PDX & Serialization +* [Serialization](serialization/README.md) * Lucene Indexing * OQL Indexing -* Functions * [Cache Loader](loader/README.md) * [Cache Writer](writer/README.md) * [Cache Listeners](listener/README.md) diff --git a/serialization/README.md b/serialization/README.md new file mode 100644 index 0000000..3829607 --- /dev/null +++ b/serialization/README.md @@ -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. +--> + +# Geode serialization example + +This is a simple example that demonstrates Java serialization, +PDX serialization, and data serialization. + +This example assumes you have installed Java and Geode. + +## Steps + +1. From the `geode-examples/serialization` directory, build the example and + run unit tests + + $ ../gradlew build + +2. Next start the locator and two servers + + $ gfsh run --file=scripts/start.gfsh + +3. Run the example to create entries in the region + + $ ../gradlew run + +4. Shut down the system: + + $ gfsh run --file=scripts/stop.gfsh diff --git a/serialization/scripts/start.gfsh b/serialization/scripts/start.gfsh new file mode 100644 index 0000000..f5d8460 --- /dev/null +++ b/serialization/scripts/start.gfsh @@ -0,0 +1,27 @@ +# +# 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. +# +start locator --name=locator --bind-address=127.0.0.1 + +start server --name=server1 --locators=127.0.0.1[10334] --server-port=0 +start server --name=server2 --locators=127.0.0.1[10334] --server-port=0 +list members + +create region --name=example-region --type=REPLICATE +describe region --name=example-region + +deploy --jar=build/libs/serialization.jar +list functions \ No newline at end of file diff --git a/serialization/scripts/stop.gfsh b/serialization/scripts/stop.gfsh new file mode 100644 index 0000000..5dd4874 --- /dev/null +++ b/serialization/scripts/stop.gfsh @@ -0,0 +1,19 @@ +# +# 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. +# +connect --locator=127.0.0.1[10334] + +shutdown --include-locators=true \ No newline at end of file diff --git a/serialization/src/main/java/org/apache/geode/examples/serialization/Country.java b/serialization/src/main/java/org/apache/geode/examples/serialization/Country.java new file mode 100644 index 0000000..9a35291 --- /dev/null +++ b/serialization/src/main/java/org/apache/geode/examples/serialization/Country.java @@ -0,0 +1,142 @@ +/* + * 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.examples.serialization; + +public class Country { + protected String name; + protected String capitol; + protected String language; + protected String currency; + protected int population; + protected Country[] neighbors; + + public Country() { + this("", "", "", "", 0); + } + + protected Country(String name, String capitol, String language, String currency, int population) { + this.name = name; + this.capitol = capitol; + this.language = language; + this.currency = currency; + this.population = population; + this.neighbors = new Country[0]; + } + + public String getName() { + return name; + } + + public String getCapitol() { + return capitol; + } + + public void setCapitol(String capitol) { + this.capitol = capitol; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public int getPopulation() { + return population; + } + + public void setPopulation(int population) { + this.population = population; + } + + public Country[] getNeighbors() { + return neighbors; + } + + public void setNeighbors(Country[] neighbors) { + this.neighbors = neighbors; + } + + public void addNeighbor(Country neighbor) { + Country[] newNeighbors = new Country[neighbors.length + 1]; + System.arraycopy(neighbors, 0, newNeighbors, 0, neighbors.length); + newNeighbors[neighbors.length] = neighbor; + neighbors = newNeighbors; + } + + public String toString() { + StringBuilder builder = new StringBuilder(); + if (name != null && !name.isEmpty()) { + builder.append(name); + builder.append(" ("); + + if (capitol != null && !capitol.isEmpty()) { + if (0 < builder.length() && '(' != builder.charAt(builder.length() - 1)) { + builder.append(", "); + } + builder.append("Capitol: "); + builder.append(capitol); + } + + if (language != null && !language.isEmpty()) { + if (0 < builder.length() && '(' != builder.charAt(builder.length() - 1)) { + builder.append(", "); + } + builder.append("Language: "); + builder.append(language); + } + + if (currency != null && !currency.isEmpty()) { + if (0 < builder.length() && '(' != builder.charAt(builder.length() - 1)) { + builder.append(", "); + } + builder.append("Currency: "); + builder.append(currency); + } + + if (0 < population) { + if (0 < builder.length() && '(' != builder.charAt(builder.length() - 1)) { + builder.append(", "); + } + builder.append("Population: "); + builder.append(population); + } + + if (neighbors != null && 0 < neighbors.length) { + if (0 < builder.length() && '(' != builder.charAt(builder.length() - 1)) { + builder.append(", "); + } + builder.append("Neighbors:"); + for (Country neighbor : neighbors) { + builder.append(' '); + builder.append(neighbor.getName()); + } + } + + builder.append(")"); + } + return builder.toString(); + } +} diff --git a/serialization/src/main/java/org/apache/geode/examples/serialization/DataSerializableCountry.java b/serialization/src/main/java/org/apache/geode/examples/serialization/DataSerializableCountry.java new file mode 100644 index 0000000..3408ae1 --- /dev/null +++ b/serialization/src/main/java/org/apache/geode/examples/serialization/DataSerializableCountry.java @@ -0,0 +1,50 @@ +/* + * 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.examples.serialization; + +import org.apache.geode.DataSerializable; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class DataSerializableCountry extends Country implements DataSerializable { + public DataSerializableCountry() { + super(); + } + + public DataSerializableCountry(String name, String capitol, String language, String currency, + int population) { + super(name, capitol, language, currency, population); + } + + @Override + public void fromData(DataInput in) throws IOException { + name = in.readUTF(); + capitol = in.readUTF(); + language = in.readUTF(); + currency = in.readUTF(); + population = in.readInt(); + } + + @Override + public void toData(DataOutput out) throws IOException { + out.writeUTF(name); + out.writeUTF(capitol); + out.writeUTF(language); + out.writeUTF(currency); + out.writeInt(population); + } +} diff --git a/serialization/src/main/java/org/apache/geode/examples/serialization/Example.java b/serialization/src/main/java/org/apache/geode/examples/serialization/Example.java new file mode 100644 index 0000000..45012ec --- /dev/null +++ b/serialization/src/main/java/org/apache/geode/examples/serialization/Example.java @@ -0,0 +1,176 @@ +/* + * 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.examples.serialization; + +import org.apache.geode.DataSerializable; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.pdx.PdxSerializable; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Set; + +public class Example { + public static final String ARENDELLE = "Arendelle"; + public static final String BORDURIA = "Borduria"; + public static final String CASCADIA = "Cascadia"; + public static final String ELBONIA = "Elbonia"; + public static final String FLORIN = "Florin"; + public static final String GRAUSTARK = "Graustark"; + public static final String LATVERIA = "Latveria"; + public static final String MARKOVIA = "Markovia"; + public static final String PARADOR = "Parador"; + public static final String SIERRA_GORDO = "Sierra Gordo"; + final Region<String, Country> region; + + public Example(Region<String, Country> region) { + this.region = region; + } + + public static void main(String[] args) { + // connect to the locator using default port 10334 + ClientCache cache = new ClientCacheFactory().addPoolLocator("127.0.0.1", 10334) + .set("log-level", "WARN").create(); + + // create a local region that matches the server region + Region<String, Country> region = + cache.<String, Country>createClientRegionFactory(ClientRegionShortcut.PROXY) + .create("example-region"); + + Example example = new Example(region); + + example.demonstrateWithoutCycle(JavaSerializableCountry.class); + example.demonstrateWithoutCycle(DataSerializableCountry.class); + example.demonstrateWithoutCycle(PdxSerializableCountry.class); + + example.demonstrateWithCycle(JavaSerializableCountry.class); + example.demonstrateWithCycle(DataSerializableCountry.class); + example.demonstrateWithCycle(PdxSerializableCountry.class); + + cache.close(); + } + + public void demonstrateWithoutCycle(Class countryClass) { + System.out.println(); + System.out.println(countryClass); + region.clear(); + insertValues(countryClass); + printValues(getKeys()); + } + + public void demonstrateWithCycle(Class countryClass) { + System.out.println(); + if (DataSerializableCountry.class.equals(countryClass) + || PdxSerializableCountry.class.equals(countryClass)) { + System.out.println("Class " + countryClass + " does not support object cycles."); + return; + } + System.out.println(countryClass); + region.clear(); + insertValues(countryClass); + updateValues(); + printValues(getKeys()); + } + + Country create(Class countryClass, String name) throws NoSuchMethodException, + InstantiationException, IllegalAccessException, InvocationTargetException { + return create(countryClass, name, name + " City"); + } + + Country create(Class countryClass, String name, String capitol) throws NoSuchMethodException, + InstantiationException, IllegalAccessException, InvocationTargetException { + return create(countryClass, name, capitol, ""); + } + + Country create(Class countryClass, String name, String capitol, String language) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, + InvocationTargetException { + return create(countryClass, name, capitol, language, "", 0); + } + + Country create(Class countryClass, String name, String capitol, String language, String currency, + int population) throws NoSuchMethodException, InstantiationException, IllegalAccessException, + InvocationTargetException { + Constructor constructor = countryClass.getConstructor( + new Class[] {String.class, String.class, String.class, String.class, int.class}); + Country country = + (Country) constructor.newInstance(name, capitol, language, currency, population); + return country; + } + + Set<String> getKeys() { + return new HashSet<>(region.keySetOnServer()); + } + + void insertValues(Class countryClass) { + try { + insertValue(create(countryClass, ARENDELLE, "Arendelle City", "Arendellii", "Arendelle Krona", + 76573)); + insertValue( + create(countryClass, BORDURIA, "SzohĂ´d", "Bordurian", "Bordurian Dinar", 1000000)); + insertValue(create(countryClass, CASCADIA, "Portland", "Pacific Northwest English", + "United States Dollar", 16029520)); + insertValue(create(countryClass, ELBONIA)); + insertValue(create(countryClass, FLORIN)); + insertValue(create(countryClass, GRAUSTARK, "Edelweiss")); + insertValue( + create(countryClass, LATVERIA, "Doomstadt", "Latverian", "Latverian Franc", 500000)); + insertValue(create(countryClass, MARKOVIA, "Markovburg", "German")); + insertValue(create(countryClass, PARADOR)); + insertValue(create(countryClass, SIERRA_GORDO, "Rio Lindo", "Spanish")); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException + | InvocationTargetException e) { + e.printStackTrace(); + } + } + + void insertValue(Country country) { + region.put(country.getName(), country); + } + + void updateValues() { + updateValue(ARENDELLE, new String[] {BORDURIA, ELBONIA, FLORIN}); + updateValue(BORDURIA, new String[] {ARENDELLE, FLORIN, GRAUSTARK, CASCADIA}); + updateValue(CASCADIA, new String[] {BORDURIA, GRAUSTARK, LATVERIA}); + updateValue(ELBONIA, new String[] {ARENDELLE, FLORIN, MARKOVIA}); + updateValue(FLORIN, new String[] {ARENDELLE, BORDURIA, ELBONIA, GRAUSTARK, MARKOVIA, PARADOR}); + updateValue(GRAUSTARK, + new String[] {BORDURIA, CASCADIA, FLORIN, LATVERIA, PARADOR, SIERRA_GORDO}); + updateValue(LATVERIA, new String[] {CASCADIA, GRAUSTARK, SIERRA_GORDO}); + updateValue(MARKOVIA, new String[] {ELBONIA, FLORIN, PARADOR}); + updateValue(PARADOR, new String[] {FLORIN, GRAUSTARK, MARKOVIA, SIERRA_GORDO}); + updateValue(SIERRA_GORDO, new String[] {GRAUSTARK, LATVERIA, PARADOR}); + } + + void updateValue(String name, String[] neighbors) { + Country country = region.get(name); + for (String neighbor : neighbors) { + final Country neighborCountry = region.get(neighbor); + country.addNeighbor(neighborCountry); + } + region.put(name, country); + } + + void printValues(Set<String> keys) { + for (String key : keys) { + Country country = region.get(key); + System.out.println(key + ": " + country); + } + } +} diff --git a/serialization/src/main/java/org/apache/geode/examples/serialization/JavaSerializableCountry.java b/serialization/src/main/java/org/apache/geode/examples/serialization/JavaSerializableCountry.java new file mode 100644 index 0000000..56ab7d7 --- /dev/null +++ b/serialization/src/main/java/org/apache/geode/examples/serialization/JavaSerializableCountry.java @@ -0,0 +1,67 @@ +/* + * 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.examples.serialization; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; +import java.io.Serializable; + +public class JavaSerializableCountry extends Country implements Serializable { + private static final long serialVersionUID = -6228801855337908064L; + + public JavaSerializableCountry() { + super(); + } + + public JavaSerializableCountry(String name, String capitol, String language, String currency, + int population) { + super(name, capitol, language, currency, population); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeUTF(name); + out.writeUTF(capitol); + out.writeUTF(language); + out.writeUTF(currency); + out.writeInt(population); + out.writeInt(neighbors.length); + for (int i = 0; i < neighbors.length; ++i) { + out.writeObject((JavaSerializableCountry) neighbors[i]); + } + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + name = in.readUTF(); + capitol = in.readUTF(); + language = in.readUTF(); + currency = in.readUTF(); + population = in.readInt(); + neighbors = new Country[in.readInt()]; + for (int i = 0; i < neighbors.length; ++i) { + neighbors[i] = (JavaSerializableCountry) in.readObject(); + } + } + + private void readObjectNoData() throws ObjectStreamException { + name = ""; + capitol = ""; + language = ""; + currency = ""; + population = 0; + neighbors = new Country[0]; + } +} diff --git a/serialization/src/main/java/org/apache/geode/examples/serialization/PdxSerializableCountry.java b/serialization/src/main/java/org/apache/geode/examples/serialization/PdxSerializableCountry.java new file mode 100644 index 0000000..024b6c9 --- /dev/null +++ b/serialization/src/main/java/org/apache/geode/examples/serialization/PdxSerializableCountry.java @@ -0,0 +1,48 @@ +/* + * 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.examples.serialization; + +import org.apache.geode.pdx.PdxReader; +import org.apache.geode.pdx.PdxSerializable; +import org.apache.geode.pdx.PdxWriter; + +public class PdxSerializableCountry extends Country implements PdxSerializable { + public PdxSerializableCountry() { + super(); + } + + public PdxSerializableCountry(String name, String capitol, String language, String currency, + int population) { + super(name, capitol, language, currency, population); + } + + @Override + public void toData(PdxWriter writer) { + writer.writeString("name", name); + writer.writeString("capitol", capitol); + writer.writeString("language", language); + writer.writeString("currency", currency); + writer.writeInt("population", population); + } + + @Override + public void fromData(PdxReader reader) { + name = reader.readString("name"); + capitol = reader.readString("capitol"); + language = reader.readString("language"); + currency = reader.readString("currency"); + population = reader.readInt("population"); + } +} diff --git a/settings.gradle b/settings.gradle index e43f7f8..6bb89ec 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,3 +29,4 @@ include 'writer' include 'listener' include 'async' include 'luceneSpatial' +include 'serialization' ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > Create new geode-example about serialization > -------------------------------------------- > > Key: GEODE-4039 > URL: https://issues.apache.org/jira/browse/GEODE-4039 > Project: Geode > Issue Type: New Feature > Components: examples > Reporter: Michael Dodge > Assignee: Michael Dodge > > Create a new example that shows how to use Java serialization, PDX > serialization, and data serialization. -- This message was sent by Atlassian JIRA (v6.4.14#64029)