http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPersonStore.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPersonStore.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPersonStore.java new file mode 100644 index 0000000..252c037 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPersonStore.java @@ -0,0 +1,275 @@ +/* + * 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.ignite.examples.datagrid.store.jdbc; + +import org.apache.ignite.*; +import org.apache.ignite.cache.store.*; +import org.apache.ignite.examples.datagrid.store.model.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.resources.*; +import org.jetbrains.annotations.*; + +import javax.cache.*; +import javax.cache.integration.*; +import java.sql.*; +import java.util.*; + +/** + * Example of {@link CacheStore} implementation that uses JDBC + * transaction with cache transactions and maps {@link Long} to {@link Person}. + * + */ +public class CacheJdbcPersonStore extends CacheStoreAdapter<Long, Person> { + /** Transaction metadata attribute name. */ + private static final String ATTR_NAME = "SIMPLE_STORE_CONNECTION"; + + /** Auto-injected store session. */ + @CacheStoreSessionResource + private CacheStoreSession ses; + + /** + * Constructor. + * + * @throws IgniteException If failed. + */ + public CacheJdbcPersonStore() throws IgniteException { + prepareDb(); + } + + /** + * Prepares database for example execution. This method will create a + * table called "PERSONS" so it can be used by store implementation. + * + * @throws IgniteException If failed. + */ + private void prepareDb() throws IgniteException { + try (Connection conn = openConnection(false); Statement st = conn.createStatement()) { + st.execute("create table if not exists PERSONS (id number unique, firstName varchar(255), " + + "lastName varchar(255))"); + + conn.commit(); + } + catch (SQLException e) { + throw new IgniteException("Failed to create database table.", e); + } + } + + /** {@inheritDoc} */ + @Override public void txEnd(boolean commit) { + Map<String, Connection> props = ses.properties(); + + try (Connection conn = props.remove(ATTR_NAME)) { + if (conn != null) { + if (commit) + conn.commit(); + else + conn.rollback(); + } + + System.out.println(">>> Transaction ended [commit=" + commit + ']'); + } + catch (SQLException e) { + throw new CacheWriterException("Failed to end transaction: " + ses.transaction(), e); + } + } + + /** {@inheritDoc} */ + @Override public Person load(Long key) { + System.out.println(">>> Loading key: " + key); + + Connection conn = null; + + try { + conn = connection(); + + try (PreparedStatement st = conn.prepareStatement("select * from PERSONS where id=?")) { + st.setString(1, key.toString()); + + ResultSet rs = st.executeQuery(); + + if (rs.next()) + return new Person(rs.getLong(1), rs.getString(2), rs.getString(3)); + } + } + catch (SQLException e) { + throw new CacheLoaderException("Failed to load object: " + key, e); + } + finally { + end(conn); + } + + return null; + } + + /** {@inheritDoc} */ + @Override public void write(Cache.Entry<? extends Long, ? extends Person> entry) { + Long key = entry.getKey(); + + Person val = entry.getValue(); + + System.out.println(">>> Putting [key=" + key + ", val=" + val + ']'); + + Connection conn = null; + + try { + conn = connection(); + + int updated; + + // Try update first. If it does not work, then try insert. + // Some databases would allow these to be done in one 'upsert' operation. + try (PreparedStatement st = conn.prepareStatement( + "update PERSONS set firstName=?, lastName=? where id=?")) { + st.setString(1, val.getFirstName()); + st.setString(2, val.getLastName()); + st.setLong(3, val.getId()); + + updated = st.executeUpdate(); + } + + // If update failed, try to insert. + if (updated == 0) { + try (PreparedStatement st = conn.prepareStatement( + "insert into PERSONS (id, firstName, lastName) values(?, ?, ?)")) { + st.setLong(1, val.getId()); + st.setString(2, val.getFirstName()); + st.setString(3, val.getLastName()); + + st.executeUpdate(); + } + } + } + catch (SQLException e) { + throw new CacheLoaderException("Failed to put object [key=" + key + ", val=" + val + ']', e); + } + finally { + end(conn); + } + } + + /** {@inheritDoc} */ + @Override public void delete(Object key) { + System.out.println(">>> Removing key: " + key); + + Connection conn = null; + + try { + conn = connection(); + + try (PreparedStatement st = conn.prepareStatement("delete from PERSONS where id=?")) { + st.setLong(1, (Long)key); + + st.executeUpdate(); + } + } + catch (SQLException e) { + throw new CacheWriterException("Failed to remove object: " + key, e); + } + finally { + end(conn); + } + } + + /** {@inheritDoc} */ + @Override public void loadCache(IgniteBiInClosure<Long, Person> clo, Object... args) { + if (args == null || args.length == 0 || args[0] == null) + throw new CacheLoaderException("Expected entry count parameter is not provided."); + + final int entryCnt = (Integer)args[0]; + + try (Connection conn = connection()) { + try (PreparedStatement st = conn.prepareStatement("select * from PERSONS")) { + try (ResultSet rs = st.executeQuery()) { + int cnt = 0; + + while (cnt < entryCnt && rs.next()) { + Person person = new Person(rs.getLong(1), rs.getString(2), rs.getString(3)); + + clo.apply(person.getId(), person); + + cnt++; + } + + System.out.println(">>> Loaded " + cnt + " values into cache."); + } + } + } + catch (SQLException e) { + throw new CacheLoaderException("Failed to load values from cache store.", e); + } + } + + /** + * @return Connection. + * @throws SQLException In case of error. + */ + private Connection connection() throws SQLException { + // If there is an ongoing transaction, + // we must reuse the same connection. + if (ses.isWithinTransaction()) { + Map<Object, Object> props = ses.properties(); + + Connection conn = (Connection)props.get(ATTR_NAME); + + if (conn == null) { + conn = openConnection(false); + + // Store connection in session properties, so it can be accessed + // for other operations on the same transaction. + props.put(ATTR_NAME, conn); + } + + return conn; + } + // Transaction can be null in case of simple load or put operation. + else + return openConnection(true); + } + + /** + * Closes allocated resources depending on transaction status. + * + * @param conn Allocated connection. + */ + private void end(@Nullable Connection conn) { + if (!ses.isWithinTransaction() && conn != null) { + // Close connection right away if there is no transaction. + try { + conn.close(); + } + catch (SQLException ignored) { + // No-op. + } + } + } + + /** + * Gets connection from a pool. + * + * @param autocommit {@code true} If connection should use autocommit mode. + * @return Pooled connection. + * @throws SQLException In case of error. + */ + private Connection openConnection(boolean autocommit) throws SQLException { + Connection conn = DriverManager.getConnection("jdbc:h2:mem:example;DB_CLOSE_DELAY=-1"); + + conn.setAutoCommit(autocommit); + + return conn; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPojoPersonStore.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPojoPersonStore.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPojoPersonStore.java new file mode 100644 index 0000000..86f3403 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/CacheJdbcPojoPersonStore.java @@ -0,0 +1,82 @@ +/* + * 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.ignite.examples.datagrid.store.jdbc; + +import org.apache.ignite.*; +import org.apache.ignite.cache.store.jdbc.*; +import org.apache.ignite.examples.datagrid.store.model.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.h2.tools.*; + +import javax.cache.*; +import java.io.*; +import java.sql.*; + +/** + * Example of {@link CacheJdbcPojoStore} implementation that uses JDBC + * transaction with cache transactions and maps {@link Long} to {@link Person}. + */ +public class CacheJdbcPojoPersonStore extends CacheJdbcPojoStore<Long, Person> { + /** + * Constructor. + * + * @throws IgniteException If failed. + */ + public CacheJdbcPojoPersonStore() throws IgniteException { + try { + // Try to connect to database server. + dataSrc = org.h2.jdbcx.JdbcConnectionPool.create("jdbc:h2:tcp://localhost/mem:ExampleDb", "sa", ""); + + resolveDialect(); + } + catch (CacheException ignore) { + // Construct example database in memory. + dataSrc = org.h2.jdbcx.JdbcConnectionPool.create("jdbc:h2:mem:ExampleDb;DB_CLOSE_DELAY=-1", "sa", ""); + + prepareDb(); + } + } + + /** + * Prepares database for example execution. This method will create a table called "PERSONS" + * so it can be used by store implementation. + * + * @throws IgniteException If failed. + */ + private void prepareDb() throws IgniteException { + File script = U.resolveIgnitePath("examples/config/store/example-database.script"); + + if (script == null) + throw new IgniteException("Failed to find example database script: " + + "examples/config/store/example-database.script"); + + try { + // Start H2 database TCP server in order to access sample in-memory database from other processes. + Server.createTcpServer("-tcpDaemon").start(); + + // Load sample data into database. + RunScript.execute(dataSrc.getConnection(), new FileReader(script)); + } + catch (SQLException e) { + throw new IgniteException("Failed to initialize database", e); + } + catch (FileNotFoundException e) { + throw new IgniteException("Failed to find example database script: " + script.getPath(), e); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/package-info.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/package-info.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/package-info.java new file mode 100644 index 0000000..ee6facb --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/jdbc/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. + */ + +/** + * <!-- Package description. --> + * Contains JDBC-based cache store implementation. + */ +package org.apache.ignite.examples.datagrid.store.jdbc; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datagrid/store/model/Person.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/store/model/Person.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/model/Person.java new file mode 100644 index 0000000..fad7816 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/model/Person.java @@ -0,0 +1,155 @@ +/* + * 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.ignite.examples.datagrid.store.model; + +import java.io.*; + +/** + * Person definition. + * + * Code generated by Apache Ignite Schema Import utility: 02/24/2015. + */ +public class Person implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private long id; + + /** Value for first name. */ + private String firstName; + + /** Value for last name. */ + private String lastName; + + /** + * Empty constructor. + */ + public Person() { + // No-op. + } + + /** + * Full constructor. + */ + public Person( + long id, + String firstName, + String lastName + ) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public long getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(long id) { + this.id = id; + } + + /** + * Gets first name. + * + * @return Value for first name. + */ + public String getFirstName() { + return firstName; + } + + /** + * Sets first name. + * + * @param firstName New value for first name. + */ + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + /** + * Gets last name. + * + * @return Value for last name. + */ + public String getLastName() { + return lastName; + } + + /** + * Sets last name. + * + * @param lastName New value for last name. + */ + public void setLastName(String lastName) { + this.lastName = lastName; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Person)) + return false; + + Person that = (Person)o; + + if (id != that.id) + return false; + + if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) + return false; + + if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = (int)(id ^ (id >>> 32)); + + res = 31 * res + (firstName != null ? firstName.hashCode() : 0); + + res = 31 * res + (lastName != null ? lastName.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Person [id=" + id + + ", firstName=" + firstName + + ", lastName=" + lastName + + "]"; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datagrid/store/package-info.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/store/package-info.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/package-info.java new file mode 100644 index 0000000..2c98e7c --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/store/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. + */ + +/** + * <!-- Package description. --> + * Demonstrates using of cache store. + */ +package org.apache.ignite.examples.datagrid.store; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicLongExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicLongExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicLongExample.java new file mode 100644 index 0000000..e83673f --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicLongExample.java @@ -0,0 +1,74 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Demonstrates a simple usage of distributed atomic long. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public final class IgniteAtomicLongExample { + /** Number of retries */ + private static final int RETRIES = 20; + + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Atomic long example started."); + + // Make name for atomic long (by which it will be known in the cluster). + String atomicName = UUID.randomUUID().toString(); + + // Initialize atomic long. + final IgniteAtomicLong atomicLong = ignite.atomicLong(atomicName, 0, true); + + System.out.println(); + System.out.println("Atomic long initial value : " + atomicLong.get() + '.'); + + // Try increment atomic long from all nodes. + // Note that this node is also part of the ignite cluster. + ignite.compute().broadcast(new IgniteCallable<Object>() { + @Override public Object call() { + for (int i = 0; i < RETRIES; i++) + System.out.println("AtomicLong value has been incremented: " + atomicLong.incrementAndGet()); + + return null; + } + }); + + System.out.println(); + System.out.println("Atomic long value after successful CAS: " + atomicLong.get()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicReferenceExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicReferenceExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicReferenceExample.java new file mode 100644 index 0000000..76c1d5e --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicReferenceExample.java @@ -0,0 +1,110 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Demonstrates a simple usage of distributed atomic reference. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public final class IgniteAtomicReferenceExample { + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Atomic reference example started."); + + // Make name of atomic reference. + final String refName = UUID.randomUUID().toString(); + + // Make value of atomic reference. + String val = UUID.randomUUID().toString(); + + // Initialize atomic reference. + IgniteAtomicReference<String> ref = ignite.atomicReference(refName, val, true); + + System.out.println("Atomic reference initial value : " + ref.get() + '.'); + + // Make closure for checking atomic reference value on cluster. + IgniteRunnable c = new ReferenceClosure(refName); + + // Check atomic reference on all cluster nodes. + ignite.compute().run(c); + + // Make new value of atomic reference. + String newVal = UUID.randomUUID().toString(); + + System.out.println("Try to change value of atomic reference with wrong expected value."); + + ref.compareAndSet("WRONG EXPECTED VALUE", newVal); // Won't change. + + // Check atomic reference on all cluster nodes. + // Atomic reference value shouldn't be changed. + ignite.compute().run(c); + + System.out.println("Try to change value of atomic reference with correct expected value."); + + ref.compareAndSet(val, newVal); + + // Check atomic reference on all cluster nodes. + // Atomic reference value should be changed. + ignite.compute().run(c); + } + + System.out.println(); + System.out.println("Finished atomic reference example..."); + System.out.println("Check all nodes for output (this node is also part of the cluster)."); + } + + /** + * Obtains atomic reference. + */ + private static class ReferenceClosure implements IgniteRunnable { + /** Reference name. */ + private final String refName; + + /** + * @param refName Reference name. + */ + ReferenceClosure(String refName) { + this.refName = refName; + } + + /** {@inheritDoc} */ + @Override public void run() { + IgniteAtomicReference<String> ref = Ignition.ignite().atomicReference(refName, null, true); + + System.out.println("Atomic reference value is " + ref.get() + '.'); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicSequenceExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicSequenceExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicSequenceExample.java new file mode 100644 index 0000000..3052da5 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicSequenceExample.java @@ -0,0 +1,91 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +/** + * Demonstrates a simple usage of distributed atomic sequence. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public final class IgniteAtomicSequenceExample { + /** Number of retries */ + private static final int RETRIES = 20; + + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Cache atomic sequence example started."); + + // Try increment atomic sequence on all cluster nodes. Note that this node is also part of the cluster. + ignite.compute().broadcast(new SequenceClosure("example-sequence")); + + System.out.println(); + System.out.println("Finished atomic sequence example..."); + System.out.println("Check all nodes for output (this node is also part of the cluster)."); + System.out.println(); + } + } + + /** + * Obtains atomic sequence. + */ + private static class SequenceClosure implements IgniteRunnable { + /** Sequence name. */ + private final String seqName; + + /** + * @param seqName Sequence name. + */ + SequenceClosure(String seqName) { + this.seqName = seqName; + } + + /** {@inheritDoc} */ + @Override public void run() { + // Create sequence. Only one concurrent call will succeed in creation. + // Rest of the callers will get already created instance. + IgniteAtomicSequence seq = Ignition.ignite().atomicSequence(seqName, 0, true); + + // First value of atomic sequence on this node. + long firstVal = seq.get(); + + System.out.println("Sequence initial value on local node: " + firstVal); + + for (int i = 0; i < RETRIES; i++) + System.out.println("Sequence [currentValue=" + seq.get() + ", afterIncrement=" + + seq.incrementAndGet() + ']'); + + System.out.println("Sequence after incrementing [expected=" + (firstVal + RETRIES) + ", actual=" + + seq.get() + ']'); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicStampedExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicStampedExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicStampedExample.java new file mode 100644 index 0000000..077ae89 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteAtomicStampedExample.java @@ -0,0 +1,117 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Demonstrates a simple usage of distributed atomic stamped. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public final class IgniteAtomicStampedExample { + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Atomic stamped example started."); + + // Make name of atomic stamped. + String stampedName = UUID.randomUUID().toString(); + + // Make value of atomic stamped. + String val = UUID.randomUUID().toString(); + + // Make stamp of atomic stamped. + String stamp = UUID.randomUUID().toString(); + + // Initialize atomic stamped. + IgniteAtomicStamped<String, String> stamped = ignite.atomicStamped(stampedName, val, stamp, true); + + System.out.println("Atomic stamped initial [value=" + stamped.value() + ", stamp=" + stamped.stamp() + ']'); + + // Make closure for checking atomic stamped. + IgniteRunnable c = new StampedUpdateClosure(stampedName); + + // Check atomic stamped on all cluster nodes. + ignite.compute().broadcast(c); + + // Make new value of atomic stamped. + String newVal = UUID.randomUUID().toString(); + + // Make new stamp of atomic stamped. + String newStamp = UUID.randomUUID().toString(); + + System.out.println("Try to change value and stamp of atomic stamped with wrong expected value and stamp."); + + stamped.compareAndSet("WRONG EXPECTED VALUE", newVal, "WRONG EXPECTED STAMP", newStamp); + + // Check atomic stamped on all cluster nodes. + // Atomic stamped value and stamp shouldn't be changed. + ignite.compute().run(c); + + System.out.println("Try to change value and stamp of atomic stamped with correct value and stamp."); + + stamped.compareAndSet(val, newVal, stamp, newStamp); + + // Check atomic stamped on all cluster nodes. + // Atomic stamped value and stamp should be changed. + ignite.compute().run(c); + } + + System.out.println(); + System.out.println("Finished atomic stamped example..."); + System.out.println("Check all nodes for output (this node is also part of the cluster)."); + } + + /** + * Performs update of on an atomic stamped variable in cache. + */ + private static class StampedUpdateClosure implements IgniteRunnable { + /** Atomic stamped variable name. */ + private final String stampedName; + + /** + * @param stampedName Atomic stamped variable name. + */ + StampedUpdateClosure(String stampedName) { + this.stampedName = stampedName; + } + + /** {@inheritDoc} */ + @Override public void run() { + IgniteAtomicStamped<String, String> stamped = Ignition.ignite(). + atomicStamped(stampedName, null, null, true); + + System.out.println("Atomic stamped [value=" + stamped.value() + ", stamp=" + stamped.stamp() + ']'); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteCountDownLatchExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteCountDownLatchExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteCountDownLatchExample.java new file mode 100644 index 0000000..3882a43 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteCountDownLatchExample.java @@ -0,0 +1,95 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Demonstrates a simple usage of distributed count down latch. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public class IgniteCountDownLatchExample { + /** Number of latch initial count */ + private static final int INITIAL_COUNT = 10; + + /** + * Executes example. + * + * @param args Command line arguments, none required. + */ + public static void main(String[] args) { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Cache atomic countdown latch example started."); + + // Make name of count down latch. + final String latchName = UUID.randomUUID().toString(); + + // Initialize count down latch. + IgniteCountDownLatch latch = ignite.countDownLatch(latchName, INITIAL_COUNT, false, true); + + System.out.println("Latch initial value: " + latch.count()); + + // Start waiting on the latch on all cluster nodes. + for (int i = 0; i < INITIAL_COUNT; i++) + ignite.compute().run(new LatchClosure(latchName)); + + // Wait for latch to go down which essentially means that all remote closures completed. + latch.await(); + + System.out.println("All latch closures have completed."); + } + + System.out.println(); + System.out.println("Finished count down latch example..."); + System.out.println("Check all nodes for output (this node is also part of the cluster)."); + } + + /** + * Closure which simply waits on the latch on all nodes. + */ + private static class LatchClosure implements IgniteRunnable { + /** Latch name. */ + private final String latchName; + + /** + * @param latchName Latch name. + */ + LatchClosure(String latchName) { + this.latchName = latchName; + } + + /** {@inheritDoc} */ + @Override public void run() { + IgniteCountDownLatch latch = Ignition.ignite().countDownLatch(latchName, 1, false, true); + + int newCnt = latch.countDown(); + + System.out.println("Counted down [newCnt=" + newCnt + ", nodeId=" + Ignition.ignite().cluster().localNode().id() + ']'); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteQueueExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteQueueExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteQueueExample.java new file mode 100644 index 0000000..a857bb0 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteQueueExample.java @@ -0,0 +1,215 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Ignite cache distributed queue example. This example demonstrates {@code FIFO} unbounded + * cache queue. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public class IgniteQueueExample { + /** Cache name. */ + private static final String CACHE_NAME = IgniteQueueExample.class.getSimpleName(); + + /** Number of retries */ + private static final int RETRIES = 20; + + /** Queue instance. */ + private static IgniteQueue<String> queue; + + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Ignite queue example started."); + + CacheConfiguration<Object, Object> cfg = new CacheConfiguration<>(); + + cfg.setCacheMode(CacheMode.PARTITIONED); + cfg.setName(CACHE_NAME); + cfg.setAtomicWriteOrderMode(CacheAtomicWriteOrderMode.PRIMARY); + + try (IgniteCache<Object, Object> cache = ignite.createCache(cfg)) { + // Make queue name. + String queueName = UUID.randomUUID().toString(); + + queue = initializeQueue(ignite, queueName); + + readFromQueue(ignite); + + writeToQueue(ignite); + + clearAndRemoveQueue(); + } + } + + System.out.println("Cache queue example finished."); + } + + /** + * Initialize queue. + * + * @param ignite Ignite. + * @param queueName Name of queue. + * @return Queue. + * @throws IgniteException If execution failed. + */ + private static IgniteQueue<String> initializeQueue(Ignite ignite, String queueName) throws IgniteException { + CollectionConfiguration colCfg = new CollectionConfiguration(); + + colCfg.setCacheName(CACHE_NAME); + + // Initialize new FIFO queue. + IgniteQueue<String> queue = ignite.queue(queueName, 0, colCfg); + + // Initialize queue items. + // We will be use blocking operation and queue size must be appropriated. + for (int i = 0; i < ignite.cluster().nodes().size() * RETRIES * 2; i++) + queue.put(Integer.toString(i)); + + System.out.println("Queue size after initializing: " + queue.size()); + + return queue; + } + + /** + * Read items from head and tail of queue. + * + * @param ignite Ignite. + * @throws IgniteException If failed. + */ + private static void readFromQueue(Ignite ignite) throws IgniteException { + final String queueName = queue.name(); + + // Read queue items on each node. + ignite.compute().broadcast(new QueueClosure(queueName, false)); + + System.out.println("Queue size after reading [expected=0, actual=" + queue.size() + ']'); + } + + /** + * Write items into queue. + * + * @param ignite Ignite. + * @throws IgniteException If failed. + */ + private static void writeToQueue(Ignite ignite) throws IgniteException { + final String queueName = queue.name(); + + // Write queue items on each node. + ignite.compute().broadcast(new QueueClosure(queueName, true)); + + System.out.println("Queue size after writing [expected=" + ignite.cluster().nodes().size() * RETRIES + + ", actual=" + queue.size() + ']'); + + System.out.println("Iterate over queue."); + + // Iterate over queue. + for (String item : queue) + System.out.println("Queue item: " + item); + } + + /** + * Clear and remove queue. + * + * @throws IgniteException If execution failed. + */ + private static void clearAndRemoveQueue() throws IgniteException { + System.out.println("Queue size before clearing: " + queue.size()); + + // Clear queue. + queue.clear(); + + System.out.println("Queue size after clearing: " + queue.size()); + + // Remove queue. + queue.close(); + + // Try to work with removed queue. + try { + queue.poll(); + } + catch (IllegalStateException expected) { + System.out.println("Expected exception - " + expected.getMessage()); + } + } + + /** + * Closure to populate or poll the queue. + */ + private static class QueueClosure implements IgniteRunnable { + /** Queue name. */ + private final String queueName; + + /** Flag indicating whether to put or poll. */ + private final boolean put; + + /** + * @param queueName Queue name. + * @param put Flag indicating whether to put or poll. + */ + QueueClosure(String queueName, boolean put) { + this.queueName = queueName; + this.put = put; + } + + /** {@inheritDoc} */ + @Override public void run() { + IgniteQueue<String> queue = Ignition.ignite().queue(queueName, 0, null); + + if (put) { + UUID locId = Ignition.ignite().cluster().localNode().id(); + + for (int i = 0; i < RETRIES; i++) { + String item = locId + "_" + Integer.toString(i); + + queue.put(item); + + System.out.println("Queue item has been added: " + item); + } + } + else { + // Take items from queue head. + for (int i = 0; i < RETRIES; i++) + System.out.println("Queue item has been read from queue head: " + queue.take()); + + // Take items from queue head once again. + for (int i = 0; i < RETRIES; i++) + System.out.println("Queue item has been read from queue head: " + queue.poll()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteSetExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteSetExample.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteSetExample.java new file mode 100644 index 0000000..cfd7d45 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/IgniteSetExample.java @@ -0,0 +1,197 @@ +/* + * 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.ignite.examples.datastructures; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; + +import java.util.*; + +/** + * Ignite cache distributed set example. + * <p> + * Remote nodes should always be started with special configuration file which + * enables P2P class loading: {@code 'ignite.{sh|bat} examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will + * start node with {@code examples/config/example-ignite.xml} configuration. + */ +public class IgniteSetExample { + /** Cache name. */ + private static final String CACHE_NAME = IgniteSetExample.class.getSimpleName(); + + /** Set instance. */ + private static IgniteSet<String> set; + + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Ignite set example started."); + + CacheConfiguration<Integer, String> cfg = new CacheConfiguration<>(); + + cfg.setCacheMode(CacheMode.PARTITIONED); + cfg.setName(CACHE_NAME); + cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + + NearCacheConfiguration<Integer, String> nearCacheCfg = new NearCacheConfiguration<>(); + + try (IgniteCache<Integer, String> cache = ignite.createCache(cfg, nearCacheCfg)) { + // Make set name. + String setName = UUID.randomUUID().toString(); + + set = initializeSet(ignite, setName); + + writeToSet(ignite); + + clearAndRemoveSet(); + } + } + + System.out.println("Ignite set example finished."); + } + + /** + * Initialize set. + * + * @param ignite Ignite. + * @param setName Name of set. + * @return Set. + * @throws IgniteException If execution failed. + */ + private static IgniteSet<String> initializeSet(Ignite ignite, String setName) throws IgniteException { + CollectionConfiguration setCfg = new CollectionConfiguration(); + + setCfg.setCacheName(CACHE_NAME); + + // Initialize new set. + IgniteSet<String> set = ignite.set(setName, setCfg); + + // Initialize set items. + for (int i = 0; i < 10; i++) + set.add(Integer.toString(i)); + + System.out.println("Set size after initializing: " + set.size()); + + return set; + } + + /** + * Write items into set. + * + * @param ignite Ignite. + * @throws IgniteException If failed. + */ + private static void writeToSet(Ignite ignite) throws IgniteException { + final String setName = set.name(); + + // Write set items on each node. + ignite.compute().broadcast(new SetClosure(setName)); + + System.out.println("Set size after writing [expected=" + (10 + ignite.cluster().nodes().size() * 5) + + ", actual=" + set.size() + ']'); + + System.out.println("Iterate over set."); + + // Iterate over set. + for (String item : set) + System.out.println("Set item: " + item); + + // Set API usage examples. + if (!set.contains("0")) + throw new RuntimeException("Set should contain '0' among its elements."); + + if (set.add("0")) + throw new RuntimeException("Set should not allow duplicates."); + + if (!set.remove("0")) + throw new RuntimeException("Set should correctly remove elements."); + + if (set.contains("0")) + throw new RuntimeException("Set should not contain '0' among its elements."); + + if (!set.add("0")) + throw new RuntimeException("Set should correctly add new elements."); + } + + /** + * Clear and remove set. + * + * @throws IgniteException If execution failed. + */ + private static void clearAndRemoveSet() throws IgniteException { + System.out.println("Set size before clearing: " + set.size()); + + // Clear set. + set.clear(); + + System.out.println("Set size after clearing: " + set.size()); + + // Remove set. + set.close(); + + System.out.println("Set was removed: " + set.removed()); + + // Try to work with removed set. + try { + set.contains("1"); + } + catch (IllegalStateException expected) { + System.out.println("Expected exception - " + expected.getMessage()); + } + } + + /** + * Closure to populate the set. + */ + private static class SetClosure implements IgniteRunnable { + /** Set name. */ + private final String setName; + + /** + * @param setName Set name. + */ + SetClosure(String setName) { + this.setName = setName; + } + + /** {@inheritDoc} */ + @Override public void run() { + IgniteSet<String> set = Ignition.ignite().set(setName, null); + + UUID locId = Ignition.ignite().cluster().localNode().id(); + + for (int i = 0; i < 5; i++) { + String item = locId + "_" + Integer.toString(i); + + set.add(item); + + System.out.println("Set item has been added: " + item); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/datastructures/package-info.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/datastructures/package-info.java b/examples/src/main/java/org/apache/ignite/examples/datastructures/package-info.java new file mode 100644 index 0000000..09b9c66 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/datastructures/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. + */ + +/** + * <!-- Package description. --> + * Demonstrates using of blocking and non-blocking queues and atomic data structures. + */ +package org.apache.ignite.examples.datastructures; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/events/EventsExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/events/EventsExample.java b/examples/src/main/java/org/apache/ignite/examples/events/EventsExample.java new file mode 100644 index 0000000..dd23e14 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/events/EventsExample.java @@ -0,0 +1,144 @@ +/* + * 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.ignite.examples.events; + +import org.apache.ignite.*; +import org.apache.ignite.compute.*; +import org.apache.ignite.events.*; +import org.apache.ignite.examples.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.resources.*; + +import java.util.*; + +import static org.apache.ignite.events.EventType.*; + +/** + * Demonstrates event consume API that allows to register event listeners on remote nodes. + * Note that ignite events are disabled by default and must be specifically enabled, + * just like in {@code examples/config/example-ignite.xml} file. + * <p> + * Remote nodes should always be started with configuration: {@code 'ignite.sh examples/config/example-ignite.xml'}. + * <p> + * Alternatively you can run {@link ExampleNodeStartup} in another JVM which will start + * node with {@code examples/config/example-ignite.xml} configuration. + */ +public class EventsExample { + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { + System.out.println(); + System.out.println(">>> Events API example started."); + + // Listen to events happening on local node. + localListen(); + + // Listen to events happening on all cluster nodes. + remoteListen(); + + // Wait for a while while callback is notified about remaining puts. + Thread.sleep(1000); + } + } + + /** + * Listen to events that happen only on local node. + * + * @throws IgniteException If failed. + */ + private static void localListen() throws IgniteException { + System.out.println(); + System.out.println(">>> Local event listener example."); + + Ignite ignite = Ignition.ignite(); + + IgnitePredicate<TaskEvent> lsnr = new IgnitePredicate<TaskEvent>() { + @Override public boolean apply(TaskEvent evt) { + System.out.println("Received task event [evt=" + evt.name() + ", taskName=" + evt.taskName() + ']'); + + return true; // Return true to continue listening. + } + }; + + // Register event listener for all local task execution events. + ignite.events().localListen(lsnr, EVTS_TASK_EXECUTION); + + // Generate task events. + ignite.compute().withName("example-event-task").run(new IgniteRunnable() { + @Override public void run() { + System.out.println("Executing sample job."); + } + }); + + // Unsubscribe local task event listener. + ignite.events().stopLocalListen(lsnr); + } + + /** + * Listen to events coming from all cluster nodes. + * + * @throws IgniteException If failed. + */ + private static void remoteListen() throws IgniteException { + System.out.println(); + System.out.println(">>> Remote event listener example."); + + // This optional local callback is called for each event notification + // that passed remote predicate listener. + IgniteBiPredicate<UUID, TaskEvent> locLsnr = new IgniteBiPredicate<UUID, TaskEvent>() { + @Override public boolean apply(UUID nodeId, TaskEvent evt) { + // Remote filter only accepts tasks whose name being with "good-task" prefix. + assert evt.taskName().startsWith("good-task"); + + System.out.println("Received task event [evt=" + evt.name() + ", taskName=" + evt.taskName()); + + return true; // Return true to continue listening. + } + }; + + // Remote filter which only accepts tasks whose name begins with "good-task" prefix. + IgnitePredicate<TaskEvent> rmtLsnr = new IgnitePredicate<TaskEvent>() { + @Override public boolean apply(TaskEvent evt) { + return evt.taskName().startsWith("good-task"); + } + }; + + Ignite ignite = Ignition.ignite(); + + // Register event listeners on all nodes to listen for task events. + ignite.events().remoteListen(locLsnr, rmtLsnr, EVTS_TASK_EXECUTION); + + // Generate task events. + for (int i = 0; i < 10; i++) { + ignite.compute().withName(i < 5 ? "good-task-" + i : "bad-task-" + i).run(new IgniteRunnable() { + // Auto-inject task session. + @TaskSessionResource + private ComputeTaskSession ses; + + @Override public void run() { + System.out.println("Executing sample job for task: " + ses.getTaskName()); + } + }); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/events/package-info.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/events/package-info.java b/examples/src/main/java/org/apache/ignite/examples/events/package-info.java new file mode 100644 index 0000000..3dd8543 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/events/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. + */ + +/** + * <!-- Package description. --> + * Demonstrates events management API. + */ +package org.apache.ignite.examples.events; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsExample.java b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsExample.java new file mode 100644 index 0000000..8bfd38d --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsExample.java @@ -0,0 +1,278 @@ +/* + * 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.ignite.examples.igfs; + +import org.apache.ignite.*; +import org.apache.ignite.igfs.*; +import org.jetbrains.annotations.*; + +import java.io.*; +import java.util.*; + +/** + * Example that shows usage of {@link org.apache.ignite.IgniteFileSystem} API. It starts a node with {@code IgniteFs} + * configured and performs several file system operations (create, write, append, read and delete + * files, create, list and delete directories). + * <p> + * Remote nodes should always be started with configuration file which includes + * IGFS: {@code 'ignite.sh examples/config/filesystem/example-igfs.xml'}. + * <p> + * Alternatively you can run {@link IgfsNodeStartup} in another JVM which will start + * node with {@code examples/config/filesystem/example-igfs.xml} configuration. + */ +public final class IgfsExample { + /** + * Executes example. + * + * @param args Command line arguments, none required. + * @throws Exception If example execution failed. + */ + public static void main(String[] args) throws Exception { + Ignite ignite = Ignition.start("examples/config/filesystem/example-igfs.xml"); + + System.out.println(); + System.out.println(">>> IGFS example started."); + + try { + // Get an instance of Ignite File System. + IgniteFileSystem fs = ignite.fileSystem("igfs"); + + // Working directory path. + IgfsPath workDir = new IgfsPath("/examples/fs"); + + // Cleanup working directory. + delete(fs, workDir); + + // Create empty working directory. + mkdirs(fs, workDir); + + // Print information for working directory. + printInfo(fs, workDir); + + // File path. + IgfsPath filePath = new IgfsPath(workDir, "file.txt"); + + // Create file. + create(fs, filePath, new byte[] {1, 2, 3}); + + // Print information for file. + printInfo(fs, filePath); + + // Append more data to previously created file. + append(fs, filePath, new byte[] {4, 5}); + + // Print information for file. + printInfo(fs, filePath); + + // Read data from file. + read(fs, filePath); + + // Delete file. + delete(fs, filePath); + + // Print information for file. + printInfo(fs, filePath); + + // Create several files. + for (int i = 0; i < 5; i++) + create(fs, new IgfsPath(workDir, "file-" + i + ".txt"), null); + + list(fs, workDir); + } + finally { + Ignition.stop(false); + } + } + + /** + * Deletes file or directory. If directory + * is not empty, it's deleted recursively. + * + * @param fs IGFS. + * @param path File or directory path. + * @throws IgniteException In case of error. + */ + private static void delete(IgniteFileSystem fs, IgfsPath path) throws IgniteException { + assert fs != null; + assert path != null; + + if (fs.exists(path)) { + boolean isFile = fs.info(path).isFile(); + + try { + fs.delete(path, true); + + System.out.println(); + System.out.println(">>> Deleted " + (isFile ? "file" : "directory") + ": " + path); + } + catch (IgfsException e) { + System.out.println(); + System.out.println(">>> Failed to delete " + (isFile ? "file" : "directory") + " [path=" + path + + ", msg=" + e.getMessage() + ']'); + } + } + else { + System.out.println(); + System.out.println(">>> Won't delete file or directory (doesn't exist): " + path); + } + } + + /** + * Creates directories. + * + * @param fs IGFS. + * @param path Directory path. + * @throws IgniteException In case of error. + */ + private static void mkdirs(IgniteFileSystem fs, IgfsPath path) throws IgniteException { + assert fs != null; + assert path != null; + + try { + fs.mkdirs(path); + + System.out.println(); + System.out.println(">>> Created directory: " + path); + } + catch (IgfsException e) { + System.out.println(); + System.out.println(">>> Failed to create a directory [path=" + path + ", msg=" + e.getMessage() + ']'); + } + + System.out.println(); + } + + /** + * Creates file and writes provided data to it. + * + * @param fs IGFS. + * @param path File path. + * @param data Data. + * @throws IgniteException If file can't be created. + * @throws IOException If data can't be written. + */ + private static void create(IgniteFileSystem fs, IgfsPath path, @Nullable byte[] data) + throws IgniteException, IOException { + assert fs != null; + assert path != null; + + try (OutputStream out = fs.create(path, true)) { + System.out.println(); + System.out.println(">>> Created file: " + path); + + if (data != null) { + out.write(data); + + System.out.println(); + System.out.println(">>> Wrote data to file: " + path); + } + } + + System.out.println(); + } + + /** + * Opens file and appends provided data to it. + * + * @param fs IGFS. + * @param path File path. + * @param data Data. + * @throws IgniteException If file can't be created. + * @throws IOException If data can't be written. + */ + private static void append(IgniteFileSystem fs, IgfsPath path, byte[] data) throws IgniteException, IOException { + assert fs != null; + assert path != null; + assert data != null; + assert fs.info(path).isFile(); + + try (OutputStream out = fs.append(path, true)) { + System.out.println(); + System.out.println(">>> Opened file: " + path); + + out.write(data); + } + + System.out.println(); + System.out.println(">>> Appended data to file: " + path); + } + + /** + * Opens file and reads it to byte array. + * + * @param fs IgniteFs. + * @param path File path. + * @throws IgniteException If file can't be opened. + * @throws IOException If data can't be read. + */ + private static void read(IgniteFileSystem fs, IgfsPath path) throws IgniteException, IOException { + assert fs != null; + assert path != null; + assert fs.info(path).isFile(); + + byte[] data = new byte[(int)fs.info(path).length()]; + + try (IgfsInputStream in = fs.open(path)) { + in.read(data); + } + + System.out.println(); + System.out.println(">>> Read data from " + path + ": " + Arrays.toString(data)); + } + + /** + * Lists files in directory. + * + * @param fs IGFS. + * @param path Directory path. + * @throws IgniteException In case of error. + */ + private static void list(IgniteFileSystem fs, IgfsPath path) throws IgniteException { + assert fs != null; + assert path != null; + assert fs.info(path).isDirectory(); + + Collection<IgfsPath> files = fs.listPaths(path); + + if (files.isEmpty()) { + System.out.println(); + System.out.println(">>> No files in directory: " + path); + } + else { + System.out.println(); + System.out.println(">>> List of files in directory: " + path); + + for (IgfsPath f : files) + System.out.println(">>> " + f.name()); + } + + System.out.println(); + } + + /** + * Prints information for file or directory. + * + * @param fs IGFS. + * @param path File or directory path. + * @throws IgniteException In case of error. + */ + private static void printInfo(IgniteFileSystem fs, IgfsPath path) throws IgniteException { + System.out.println(); + System.out.println("Information for " + path + ": " + fs.info(path)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsMapReduceExample.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsMapReduceExample.java b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsMapReduceExample.java new file mode 100644 index 0000000..ed0abe4 --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsMapReduceExample.java @@ -0,0 +1,249 @@ +/* + * 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.ignite.examples.igfs; + +import org.apache.ignite.*; +import org.apache.ignite.compute.*; +import org.apache.ignite.igfs.*; +import org.apache.ignite.igfs.mapreduce.*; +import org.apache.ignite.igfs.mapreduce.records.*; + +import java.io.*; +import java.util.*; + +/** + * Example that shows how to use {@link org.apache.ignite.igfs.mapreduce.IgfsTask} to find lines matching particular pattern in the file in pretty + * the same way as {@code grep} command does. + * <p> + * Remote nodes should always be started with configuration file which includes + * IGFS: {@code 'ignite.sh examples/config/filesystem/example-igfs.xml'}. + * <p> + * Alternatively you can run {@link IgfsNodeStartup} in another JVM which will start + * node with {@code examples/config/filesystem/example-igfs.xml} configuration. + */ +public class IgfsMapReduceExample { + /** + * Executes example. + * + * @param args Command line arguments. First argument is file name, second argument is regex to look for. + * @throws Exception If failed. + */ + public static void main(String[] args) throws Exception { + if (args.length == 0) + System.out.println("Please provide file name and regular expression."); + else if (args.length == 1) + System.out.println("Please provide regular expression."); + else { + try (Ignite ignite = Ignition.start("examples/config/filesystem/example-igfs.xml")) { + System.out.println(); + System.out.println(">>> IGFS map reduce example started."); + + // Prepare arguments. + String fileName = args[0]; + + File file = new File(fileName); + + String regexStr = args[1]; + + // Get an instance of Ignite File System. + IgniteFileSystem fs = ignite.fileSystem("igfs"); + + // Working directory path. + IgfsPath workDir = new IgfsPath("/examples/fs"); + + // Write file to IGFS. + IgfsPath fsPath = new IgfsPath(workDir, file.getName()); + + writeFile(fs, fsPath, file); + + Collection<Line> lines = fs.execute(new GrepTask(), IgfsNewLineRecordResolver.NEW_LINE, + Collections.singleton(fsPath), regexStr); + + if (lines.isEmpty()) { + System.out.println(); + System.out.println("No lines were found."); + } + else { + for (Line line : lines) + print(line.fileLine()); + } + } + } + } + + /** + * Write file to the Ignite file system. + * + * @param fs Ignite file system. + * @param fsPath Ignite file system path. + * @param file File to write. + * @throws Exception In case of exception. + */ + private static void writeFile(IgniteFileSystem fs, IgfsPath fsPath, File file) throws Exception { + System.out.println(); + System.out.println("Copying file to IGFS: " + file); + + try ( + IgfsOutputStream os = fs.create(fsPath, true); + FileInputStream fis = new FileInputStream(file) + ) { + byte[] buf = new byte[2048]; + + int read = fis.read(buf); + + while (read != -1) { + os.write(buf, 0, read); + + read = fis.read(buf); + } + } + } + + /** + * Print particular string. + * + * @param str String. + */ + private static void print(String str) { + System.out.println(">>> " + str); + } + + /** + * Grep task. + */ + private static class GrepTask extends IgfsTask<String, Collection<Line>> { + /** {@inheritDoc} */ + @Override public IgfsJob createJob(IgfsPath path, IgfsFileRange range, + IgfsTaskArgs<String> args) { + return new GrepJob(args.userArgument()); + } + + /** {@inheritDoc} */ + @Override public Collection<Line> reduce(List<ComputeJobResult> results) { + Collection<Line> lines = new TreeSet<>(new Comparator<Line>() { + @Override public int compare(Line line1, Line line2) { + return line1.rangePosition() < line2.rangePosition() ? -1 : + line1.rangePosition() > line2.rangePosition() ? 1 : line1.lineIndex() - line2.lineIndex(); + } + }); + + for (ComputeJobResult res : results) { + if (res.getException() != null) + throw res.getException(); + + Collection<Line> line = res.getData(); + + if (line != null) + lines.addAll(line); + } + + return lines; + } + } + + /** + * Grep job. + */ + private static class GrepJob extends IgfsInputStreamJobAdapter { + /** Regex string. */ + private final String regex; + + /** + * Constructor. + * + * @param regex Regex string. + */ + private GrepJob(String regex) { + this.regex = regex; + } + + /** {@inheritDoc} */ + @Override public Object execute(IgniteFileSystem igfs, IgfsRangeInputStream in) throws IgniteException, IOException { + Collection<Line> res = null; + + long start = in.startOffset(); + + try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) { + int ctr = 0; + + String line = br.readLine(); + + while (line != null) { + if (line.matches(".*" + regex + ".*")) { + if (res == null) + res = new HashSet<>(); + + res.add(new Line(start, ctr++, line)); + } + + line = br.readLine(); + } + } + + return res; + } + } + + /** + * Single file line with it's position. + */ + private static class Line { + /** Line start position in the file. */ + private long rangePos; + + /** Matching line index within the range. */ + private final int lineIdx; + + /** File line. */ + private String line; + + /** + * Constructor. + * + * @param rangePos Range position. + * @param lineIdx Matching line index within the range. + * @param line File line. + */ + private Line(long rangePos, int lineIdx, String line) { + this.rangePos = rangePos; + this.lineIdx = lineIdx; + this.line = line; + } + + /** + * @return Range position. + */ + public long rangePosition() { + return rangePos; + } + + /** + * @return Matching line index within the range. + */ + public int lineIndex() { + return lineIdx; + } + + /** + * @return File line. + */ + public String fileLine() { + return line; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsNodeStartup.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsNodeStartup.java b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsNodeStartup.java new file mode 100644 index 0000000..20ddcbd --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/igfs/IgfsNodeStartup.java @@ -0,0 +1,41 @@ +/* + * 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.ignite.examples.igfs; + +import org.apache.ignite.*; + +/** + * Starts up an empty node with IGFS configuration. + * You can also start a stand-alone Ignite instance by passing the path + * to configuration file to {@code 'ignite.{sh|bat}'} script, like so: + * {@code 'ignite.sh examples/config/filesystem/example-igfs.xml'}. + * <p> + * The difference is that running this class from IDE adds all example classes to classpath + * but running from command line doesn't. + */ +public class IgfsNodeStartup { + /** + * Start up an empty node with specified cache configuration. + * + * @param args Command line arguments, none required. + * @throws IgniteException If example execution failed. + */ + public static void main(String[] args) throws IgniteException { + Ignition.start("examples/config/filesystem/example-igfs.xml"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b473e309/examples/src/main/java/org/apache/ignite/examples/igfs/package-info.java ---------------------------------------------------------------------- diff --git a/examples/src/main/java/org/apache/ignite/examples/igfs/package-info.java b/examples/src/main/java/org/apache/ignite/examples/igfs/package-info.java new file mode 100644 index 0000000..6a48c2c --- /dev/null +++ b/examples/src/main/java/org/apache/ignite/examples/igfs/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. + */ + +/** + * <!-- Package description. --> + * Demonstrates usage of Ignite File System. + */ +package org.apache.ignite.examples.igfs;