View Javadoc
1   package org.synchronoss.cpo.cassandra;
2   
3   /*-
4    * [[
5    * cassandra
6    * ==
7    * Copyright (C) 2003 - 2026 Exaxis LLC, Synchronoss Technologies Inc
8    * ==
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ]]
23   */
24  
25  import com.datastax.oss.driver.api.core.CqlSession;
26  import java.io.Serializable;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  import org.synchronoss.cpo.core.CpoException;
30  
31  /**
32   * How a {@link CassandraCpoAdapter} obtains its sessions. Cassandra sessions are long-lived and
33   * shared, so unlike the JDBC connection strategy there is no per-call release; if the read cluster
34   * ever fails to produce a session, the strategy permanently fails over to the write cluster for
35   * reads. This mirrors the composition shape of the JDBC JdbcConnectionStrategy — promote it to an
36   * interface if a second acquisition behavior ever appears.
37   *
38   * @author david berry
39   */
40  class CassandraSessionStrategy implements Serializable {
41  
42    /** Version Id for this class. */
43    private static final long serialVersionUID = 1L;
44  
45    private static final Logger logger = LoggerFactory.getLogger(CassandraSessionStrategy.class);
46  
47    private final ClusterDataSource readDataSource;
48    private final ClusterDataSource writeDataSource;
49    private boolean invalidReadSession = false;
50  
51    /**
52     * Constructs a CassandraSessionStrategy
53     *
54     * @param readDataSource The datasource used for read sessions
55     * @param writeDataSource The datasource used for write sessions
56     */
57    CassandraSessionStrategy(ClusterDataSource readDataSource, ClusterDataSource writeDataSource) {
58      this.readDataSource = readDataSource;
59      this.writeDataSource = writeDataSource;
60    }
61  
62    /**
63     * Gets the session for read operations
64     *
65     * @return A Session bean for reading
66     * @throws CpoException An exception occurred
67     */
68    CqlSession getReadSession() throws CpoException {
69      CqlSession session;
70  
71      try {
72        if (!invalidReadSession) {
73          session = readDataSource.getSession();
74        } else {
75          session = writeDataSource.getSession();
76        }
77      } catch (Exception e) {
78        invalidReadSession = true;
79  
80        String msg = "getReadSession(): failed";
81        logger.error(msg, e);
82  
83        session = getWriteSession();
84      }
85  
86      return session;
87    }
88  
89    /**
90     * Gets the session for write operations
91     *
92     * @return A Session bean for writing
93     * @throws CpoException An exception occurred
94     */
95    CqlSession getWriteSession() throws CpoException {
96      CqlSession session;
97  
98      try {
99        session = writeDataSource.getSession();
100     } catch (Throwable t) {
101       String msg = "getWriteSession(): failed";
102       logger.error(msg, t);
103       throw new CpoException(msg, t);
104     }
105 
106     return session;
107   }
108 }