com.datastax.stargate.sdk.rest.TableClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stargate-sdk Show documentation
Show all versions of stargate-sdk Show documentation
Connect to Stargate Data Gateway
/*
* Copyright DataStax, Inc.
*
* Licensed 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 com.datastax.stargate.sdk.rest;
import static com.datastax.stargate.sdk.utils.JsonUtils.marshall;
import static com.datastax.stargate.sdk.utils.JsonUtils.unmarshallType;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.datastax.stargate.sdk.StargateClientNode;
import com.datastax.stargate.sdk.StargateHttpClient;
import com.datastax.stargate.sdk.core.ApiResponse;
import com.datastax.stargate.sdk.core.ApiResponseHttp;
import com.datastax.stargate.sdk.core.ResultPage;
import com.datastax.stargate.sdk.rest.domain.ColumnDefinition;
import com.datastax.stargate.sdk.rest.domain.CreateIndex;
import com.datastax.stargate.sdk.rest.domain.CreateTable;
import com.datastax.stargate.sdk.rest.domain.IndexDefinition;
import com.datastax.stargate.sdk.rest.domain.Row;
import com.datastax.stargate.sdk.rest.domain.RowMapper;
import com.datastax.stargate.sdk.rest.domain.RowResultPage;
import com.datastax.stargate.sdk.rest.domain.SearchTableQuery;
import com.datastax.stargate.sdk.rest.domain.SortField;
import com.datastax.stargate.sdk.rest.domain.TableDefinition;
import com.datastax.stargate.sdk.rest.domain.TableOptions;
import com.datastax.stargate.sdk.utils.Assert;
import com.datastax.stargate.sdk.utils.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
/**
* Operate on Tables in Cassandra.
*
* @author Cedrick LUNVEN (@clunven)
*/
public class TableClient {
/** URL Parts. */
public static final String PATH_COLUMNS = "/columns";
/** URL Parts. */
public static final String PATH_INDEXES = "/indexes";
/** Http Client with load balancing anf failover. */
private final StargateHttpClient stargateHttpClient;
/** Namespace. */
private KeyspaceClient keyspaceClient;
/** Collection name. */
private String tableName;
/** Hold a reference to client to keep singletons.*/
private Map columnsClient = new HashMap<>();
/** Hold a reference to client to keep singletons.*/
private Map indexsClient = new HashMap<>();
private static final TypeReference>> TYPE_LIST_COLUMNS =
new TypeReference>>() {};
private static final TypeReference>>> TYPE_RESULTS =
new TypeReference>>>() {};
private static final TypeReference> TYPE_LIST_INDEX =
new TypeReference>() {};
/**
* Full constructor.
*
* @param stargateHttpClient
* stargateHttpClient
* @param keyspaceClient
* KeyspaceClient
* @param tableName
* name of the table
*/
public TableClient(StargateHttpClient stargateHttpClient, KeyspaceClient keyspaceClient, String tableName) {
this.stargateHttpClient = stargateHttpClient;
this.keyspaceClient = keyspaceClient;
this.tableName = tableName;
Assert.notNull(keyspaceClient, "keyspaceClient");
Assert.hasLength(tableName, "tableName");
}
// ---------------------------------
// ---- CRUD ----
// ---------------------------------
/**
* Get a table.
*
* @see Reference Documentation
*
* @return metadata of the collection if its exist or empty
*/
public Optional find() {
return keyspaceClient.tables()
.filter(t -> tableName.equalsIgnoreCase(t.getName()))
.findFirst();
}
/**
* Check if the table exist.
*
* @return boolean
*/
public boolean exist() {
return keyspaceClient.tableNames()
.anyMatch(tableName::equals);
}
/**
* Create a table.
*
* @see Reference Documentation
*
* @param tcr creation request
*/
public void create(CreateTable tcr) {
tcr.setName(tableName);
Assert.notNull(tcr, "CreateTable");
stargateHttpClient.POST(keyspaceClient.tablesSchemaResource, marshall(tcr));
}
/**
* Replace a table definition (table options only).
*
* @see Reference Documentation
*
* @param to TableOptions
*/
public void updateOptions(TableOptions to) {
Assert.notNull(to, "TableCreationRequest");
CreateTable ct = CreateTable.builder().build();
ct.setPrimaryKey(null);
ct.setColumnDefinitions(null);
ct.setName(tableName);
ct.setTableOptions(to);
stargateHttpClient.PUT(tableSchemaResource, marshall(ct));
}
/**
* Delete a table.
*
* @see Reference Documentation
*/
public void delete() {
stargateHttpClient.DELETE(tableSchemaResource);
}
// ---------------------------------
// ---- DATA ----
// ---------------------------------
/**
* Add Rows.
*
* @see Reference Documentation
*
* @param record
* map of recors
*/
public void upsert(Map record) {
Assert.notNull(record, "New Record");
Assert.isTrue(!record.isEmpty(), "New record should not be empty");
stargateHttpClient.POST(tableResource, marshall(record));
}
/**
* Search a table.
*
* @see Reference Documentation
*
* @param query
* search params with filters and ordering
* @return RowResultPage
*/
public RowResultPage search(SearchTableQuery query) {
// Parameters validation
Assert.notNull(query, "query");
// Invoke Http endpint
ApiResponseHttp res = stargateHttpClient.GET(tableResource, buildSearchUrlSuffix(query));
// Marshall results
ApiResponse>> result = unmarshallType(res.getBody(), TYPE_RESULTS);
// Build result
return new RowResultPage(
query.getPageSize(),
result.getPageState(),
result.getData().stream()
.map(map -> {
Row r = new Row();
for (Entry val : map.entrySet()) {
r.put(val.getKey(), val.getValue());
}
return r;
})
.collect(Collectors.toList()));
}
/**
* Retrieve a set of Rows from Primary key value.
*
* @see Reference Documentation
*
* @param
* marshalling bean
* @param query
* SearchTableQuery
* @param mapper
* mapping result to bean with a mapper
* @return ResultPage
* pageable result
*/
public ResultPage search(SearchTableQuery query, RowMapper mapper) {
RowResultPage rrp = search(query);
return new ResultPage(
rrp.getPageSize(),
rrp.getPageState().orElse(null),
rrp.getResults().stream()
.map(mapper::map)
.collect(Collectors.toList()));
}
/**
* Build URL suffix from the filtered and sorted fields.
*
* @param query
* SearchTableQuery
* @return
* suffix for the URL
*/
private String buildSearchUrlSuffix(SearchTableQuery query) {
try {
StringBuilder sbUrl = new StringBuilder();
// Add query Params
sbUrl.append("?page-size=" + query.getPageSize());
// Depending on query you forge your URL
if (query.getPageState().isPresent()) {
sbUrl.append("&page-state=" +
URLEncoder.encode(query.getPageState().get(), StandardCharsets.UTF_8.toString()));
}
if (query.getWhere().isPresent()) {
sbUrl.append("&where=" +
URLEncoder.encode(query.getWhere().get(), StandardCharsets.UTF_8.toString()));
}
// Fields to retrieve
if (null != query.getFieldsToRetrieve() && !query.getFieldsToRetrieve().isEmpty()) {
sbUrl.append("&fields=" +
URLEncoder.encode(
String.join(",", query.getFieldsToRetrieve()), StandardCharsets.UTF_8.toString()));
}
// Fields to sort on
if (null != query.getFieldsToSort() && !query.getFieldsToSort().isEmpty()) {
Map sortFields = new LinkedHashMap<>();
for (SortField sf : query.getFieldsToSort()) {
sortFields.put(sf.getFieldName(), sf.getOrder().name());
}
sbUrl.append("&sort=" + URLEncoder.encode(JsonUtils.mapAsJson(sortFields), StandardCharsets.UTF_8.toString()));
}
return sbUrl.toString();
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Cannot enode URL", e);
}
}
// ---------------------------------
// ---- Columns ----
// ---------------------------------
/**
* Retrieve All columns.
*
* @see Reference Documentation
*
* @return
* Sream of {@link ColumnDefinition} to describe a table
*/
public Stream columns() {
ApiResponseHttp res = stargateHttpClient.GET(columnsSchemaResource);;
return unmarshallType(res.getBody(), TYPE_LIST_COLUMNS)
.getData().stream()
.collect(Collectors.toSet()).stream();
}
/**
* Create a Column.
*
* @see Reference Documentation
*
*
* @param colName String
* @param cd ColumnDefinition
*/
public void createColumn(String colName, ColumnDefinition cd) {
column(colName).create(cd);
}
/**
* Retrieve All column names.
*
* @return
* a list of columns names;
*/
public Stream columnNames() {
return columns().map(ColumnDefinition::getName);
}
// ---------------------------------
// ---- Indices ----
// ---------------------------------
/**
* Retrieve All indexes for a table.
*
* @see Reference Documentation
*
* @return
* Stream of {@link IndexDefinition} to describe a table
*/
public Stream indexes() {
ApiResponseHttp res = stargateHttpClient.GET(indexesSchemaResource);
return unmarshallType(res.getBody(), TYPE_LIST_INDEX)
.stream()
.collect(Collectors.toSet()).stream();
}
/**
* Create an index.
*
* @see Reference Documentation
*
* @param idxName String
* @param ci CreateIndex
*/
public void createIndex(String idxName, CreateIndex ci) {
index(idxName).create(ci);
}
/**
* Retrieve All indexes names.
*
* @return
* a list of columns names;
*/
public Stream indexesNames() {
return indexes().map(IndexDefinition::getIndex_name);
}
// ---------------------------------
// ---- Sub Resources ----
// ---------------------------------
/**
* Move to columns client
*
* @param columnId String
* @return ColumnsClient
*/
public ColumnsClient column(String columnId) {
Assert.hasLength(columnId, "columnName");
if (!columnsClient.containsKey(columnId)) {
columnsClient.put(columnId, new ColumnsClient(stargateHttpClient, this, columnId));
}
return columnsClient.get(columnId);
}
/**
* Move to columns client
*
* @param indexName String
* @return IndexClient
*/
public IndexClient index(String indexName) {
Assert.hasLength(indexName, "indexName");
if (!indexsClient.containsKey(indexName)) {
indexsClient.put(indexName, new IndexClient(stargateHttpClient, this, indexName));
}
return indexsClient.get(indexName);
}
/**
* Move to the Table client
*
* @param keys Object
* @return KeyClient
*/
public KeyClient key(Object... keys) {
Assert.notNull(keys, "key");
return new KeyClient(stargateHttpClient, this, keys);
}
// ---------------------------------
// ---- Resources ----
// ---------------------------------
/**
* /v2/schemas/keyspaces/{keyspace}/tables/{tableName}
*/
public Function tableSchemaResource =
(node) -> keyspaceClient.tablesSchemaResource.apply(node) + "/" + tableName;
/**
* /v2/keyspaces/{keyspace}/tables/{tableName}
*/
public Function tableResource =
(node) -> keyspaceClient.keyspaceResource.apply(node) + "/" + tableName;
/**
* /v2/schemas/keyspaces/{keyspace}/tables/{tableName}/columns
*/
public Function columnsSchemaResource =
(node) -> tableSchemaResource.apply(node) + PATH_COLUMNS;
/**
* /v2/schemas/keyspaces/{keyspace}/tables/{tableName}/indexes
*/
public Function indexesSchemaResource =
(node) -> tableSchemaResource.apply(node) + PATH_INDEXES;
/**
* Getter accessor for attribute 'tableName'.
*
* @return current value of 'tableName'
*/
public String getTableName() {
return tableName;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy