Split out datastore implementation from aaa-shiro
[aaa.git] / aaa-idm-store-h2 / src / main / java / org / opendaylight / aaa / datastore / h2 / DomainStore.java
1 /*
2  * Copyright (c) 2014, 2017 Hewlett-Packard Development Company, L.P. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.aaa.datastore.h2;
9
10 import static java.util.Objects.requireNonNull;
11
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import java.sql.Connection;
14 import java.sql.PreparedStatement;
15 import java.sql.ResultSet;
16 import java.sql.SQLException;
17 import java.sql.Statement;
18 import org.apache.commons.text.StringEscapeUtils;
19 import org.opendaylight.aaa.api.model.Domain;
20 import org.opendaylight.aaa.api.model.Domains;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Domain store.
26  *
27  * @author peter.mellquist@hp.com
28  *
29  */
30 public class DomainStore extends AbstractStore<Domain> {
31     private static final Logger LOG = LoggerFactory.getLogger(DomainStore.class);
32
33     public static final String SQL_ID = "domainid";
34     public static final String SQL_NAME = "name";
35     public static final String SQL_DESCR = "description";
36     public static final String SQL_ENABLED = "enabled";
37     private static final String TABLE_NAME = "DOMAINS";
38
39     public DomainStore(final ConnectionProvider dbConnectionFactory) {
40         super(dbConnectionFactory, TABLE_NAME);
41     }
42
43     @Override
44     protected String getTableCreationStatement() {
45         return "CREATE TABLE DOMAINS "
46                 + "(domainid   VARCHAR(128)      PRIMARY KEY,"
47                 + "name        VARCHAR(128)      UNIQUE NOT NULL, "
48                 + "description VARCHAR(128)      , "
49                 + "enabled     INTEGER           NOT NULL)";
50     }
51
52     @Override
53     protected Domain fromResultSet(final ResultSet rs) throws SQLException {
54         Domain domain = new Domain();
55         domain.setDomainid(rs.getString(SQL_ID));
56         domain.setName(rs.getString(SQL_NAME));
57         domain.setDescription(rs.getString(SQL_DESCR));
58         domain.setEnabled(rs.getInt(SQL_ENABLED) == 1);
59         return domain;
60     }
61
62     public Domains getDomains() throws StoreException {
63         Domains domains = new Domains();
64         domains.setDomains(listAll());
65         return domains;
66     }
67
68     protected Domains getDomains(final String domainName) throws StoreException {
69         LOG.debug("getDomains for: {}", domainName);
70         Domains domains = new Domains();
71         try (Connection conn = dbConnect();
72              PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM DOMAINS WHERE name = ?")) {
73             pstmt.setString(1, domainName);
74             LOG.debug("query string: {}", pstmt);
75             domains.setDomains(listFromStatement(pstmt));
76         } catch (SQLException e) {
77             LOG.error("Error listing domains matching {}", domainName, e);
78             throw new StoreException("Error listing domains", e);
79         }
80         return domains;
81     }
82
83     protected Domain getDomain(final String id) throws StoreException {
84         try (Connection conn = dbConnect();
85              PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM DOMAINS WHERE domainid = ? ")) {
86             pstmt.setString(1, id);
87             LOG.debug("query string: {}", pstmt);
88             return firstFromStatement(pstmt);
89         } catch (SQLException e) {
90             LOG.error("Error retrieving domain {}", id, e);
91             throw new StoreException("Error loading domain", e);
92         }
93     }
94
95     public Domain createDomain(final Domain domain) throws StoreException {
96         requireNonNull(domain);
97         requireNonNull(domain.getName());
98         requireNonNull(domain.isEnabled());
99         String query = "insert into DOMAINS (domainid,name,description,enabled) values(?, ?, ?, ?)";
100         try (Connection conn = dbConnect();
101              PreparedStatement statement = conn.prepareStatement(query)) {
102             statement.setString(1, domain.getName());
103             statement.setString(2, domain.getName());
104             statement.setString(3, domain.getDescription());
105             statement.setInt(4, domain.isEnabled() ? 1 : 0);
106             int affectedRows = statement.executeUpdate();
107             if (affectedRows == 0) {
108                 throw new StoreException("Creating domain failed, no rows affected.");
109             }
110             domain.setDomainid(domain.getName());
111             return domain;
112         } catch (SQLException e) {
113             LOG.error("Error creating domain {}", domain.getName(), e);
114             throw new StoreException("Error creating domain", e);
115         }
116     }
117
118     protected Domain putDomain(final Domain domain) throws StoreException {
119         Domain savedDomain = this.getDomain(domain.getDomainid());
120         if (savedDomain == null) {
121             return null;
122         }
123
124         if (domain.getDescription() != null) {
125             savedDomain.setDescription(domain.getDescription());
126         }
127         if (domain.getName() != null) {
128             savedDomain.setName(domain.getName());
129         }
130         if (domain.isEnabled() != null) {
131             savedDomain.setEnabled(domain.isEnabled());
132         }
133
134         String query = "UPDATE domains SET description = ?, enabled = ?, name = ? WHERE domainid = ?";
135         try (Connection conn = dbConnect();
136              PreparedStatement statement = conn.prepareStatement(query)) {
137             statement.setString(1, savedDomain.getDescription());
138             statement.setInt(2, savedDomain.isEnabled() ? 1 : 0);
139             statement.setString(3, savedDomain.getName());
140             statement.setString(4, savedDomain.getDomainid());
141             statement.executeUpdate();
142         } catch (SQLException e) {
143             LOG.error("Error updating domain {}", domain.getDomainid(), e);
144             throw new StoreException("Error updating domain", e);
145         }
146
147         return savedDomain;
148     }
149
150     @SuppressFBWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE")
151     protected Domain deleteDomain(String domainid) throws StoreException {
152         domainid = StringEscapeUtils.escapeHtml4(domainid);
153         Domain deletedDomain = this.getDomain(domainid);
154         if (deletedDomain == null) {
155             return null;
156         }
157         String query = String.format("DELETE FROM DOMAINS WHERE domainid = '%s'", domainid);
158         try (Connection conn = dbConnect();
159              Statement statement = conn.createStatement()) {
160             int deleteCount = statement.executeUpdate(query);
161             LOG.debug("deleted {} records", deleteCount);
162             return deletedDomain;
163         } catch (SQLException e) {
164             LOG.error("Error deleting domain {}", domainid, e);
165             throw new StoreException("Error deleting domain", e);
166         }
167     }
168 }