Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2017 Netflix, 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.netflix.metacat.metadata.mysql;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.netflix.metacat.common.QualifiedName;
import com.netflix.metacat.common.dto.DefinitionMetadataDto;
import com.netflix.metacat.common.dto.HasDataMetadata;
import com.netflix.metacat.common.dto.HasDefinitionMetadata;
import com.netflix.metacat.common.dto.HasMetadata;
import com.netflix.metacat.common.json.MetacatJson;
import com.netflix.metacat.common.json.MetacatJsonException;
import com.netflix.metacat.common.server.connectors.exception.InvalidMetadataException;
import com.netflix.metacat.common.server.properties.Config;
import com.netflix.metacat.common.server.usermetadata.BaseUserMetadataService;
import com.netflix.metacat.common.server.usermetadata.GetMetadataInterceptorParameters;
import com.netflix.metacat.common.server.usermetadata.MetadataInterceptor;
import com.netflix.metacat.common.server.usermetadata.UserMetadataServiceException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.sql.Types;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
* User metadata service.
*
* Definition metadata (business metadata about the logical schema definition) is stored in two tables. Definition
* metadata about the partitions are stored in 'partition_definition_metadata' table. Definition metadata about the
* catalogs, databases and tables are stored in 'definition_metadata' table.
*
* Data metadata (metadata about the data stored in the location referred by the schema). This information is stored in
* 'data_metadata' table.
*/
@Slf4j
@SuppressFBWarnings
@Transactional("metadataTxManager")
public class MysqlUserMetadataService extends BaseUserMetadataService {
private final MetacatJson metacatJson;
private final Config config;
private JdbcTemplate jdbcTemplate;
private final MetadataInterceptor metadataInterceptor;
/**
* Constructor.
*
* @param jdbcTemplate jdbc template
* @param metacatJson json utility
* @param config config
* @param metadataInterceptor metadata interceptor
*/
public MysqlUserMetadataService(
final JdbcTemplate jdbcTemplate,
final MetacatJson metacatJson,
final Config config,
final MetadataInterceptor metadataInterceptor
) {
this.metacatJson = metacatJson;
this.config = config;
this.jdbcTemplate = jdbcTemplate;
this.metadataInterceptor = metadataInterceptor;
}
@Override
public void saveMetadata(final String userId, final HasMetadata holder, final boolean merge) {
super.saveMetadata(userId, holder, merge);
}
@Override
public void populateMetadata(final HasMetadata holder, final ObjectNode definitionMetadata,
final ObjectNode dataMetadata) {
super.populateMetadata(holder, definitionMetadata, dataMetadata);
}
@Nonnull
@Override
@Transactional(readOnly = true)
public Optional getDefinitionMetadataWithInterceptor(
@Nonnull final QualifiedName name,
final GetMetadataInterceptorParameters getMetadataInterceptorParameters) {
//not applying interceptor
final Optional retData = getDefinitionMetadata(name);
retData.ifPresent(objectNode ->
this.metadataInterceptor.onRead(this, name, objectNode, getMetadataInterceptorParameters));
return retData;
}
@Override
public void softDeleteDataMetadata(
final String user,
@Nonnull final List uris
) {
try {
final List> subLists = Lists.partition(uris, config.getUserMetadataMaxInClauseItems());
for (List subUris : subLists) {
_softDeleteDataMetadata(user, subUris);
}
} catch (Exception e) {
final String message = String.format("Failed deleting the data metadata for %s", uris);
log.error(message, e);
throw new UserMetadataServiceException(message, e);
}
}
@Override
public void deleteDataMetadata(
@Nonnull final List uris
) {
deleteDataMetadatasWithBatch(uris, true);
}
@Override
public void deleteDataMetadataDeletes(
@Nonnull final List uris
) {
deleteDataMetadatasWithBatch(uris, false);
}
private void deleteDataMetadatasWithBatch(final List uris, final boolean removeDataMetadata) {
try {
final List> subLists = Lists.partition(uris, config.getUserMetadataMaxInClauseItems());
for (List subUris : subLists) {
_deleteDataMetadata(subUris, removeDataMetadata);
}
} catch (Exception e) {
final String message = String.format("Failed deleting the data metadata for %s", uris);
log.error(message, e);
throw new UserMetadataServiceException(message, e);
}
}
@Override
public void deleteDefinitionMetadata(
@Nonnull final List names
) {
try {
final List> subLists =
Lists.partition(names, config.getUserMetadataMaxInClauseItems());
for (List subNames : subLists) {
_deleteDefinitionMetadata(subNames);
}
} catch (Exception e) {
final String message = String.format("Failed deleting the definition metadata for %s", names);
log.error(message, e);
throw new UserMetadataServiceException(message, e);
}
}
@Override
public void deleteMetadata(final String userId, final List holders) {
try {
final List> subLists =
Lists.partition(holders, config.getUserMetadataMaxInClauseItems());
for (List hasMetadatas : subLists) {
final List names = hasMetadatas.stream()
.filter(m -> m instanceof HasDefinitionMetadata)
.map(m -> ((HasDefinitionMetadata) m).getDefinitionName())
.collect(Collectors.toList());
if (!names.isEmpty()) {
_deleteDefinitionMetadata(names);
}
if (config.canSoftDeleteDataMetadata()) {
final List uris = hasMetadatas.stream()
.filter(m -> m instanceof HasDataMetadata && ((HasDataMetadata) m).isDataExternal())
.map(m -> ((HasDataMetadata) m).getDataUri()).collect(Collectors.toList());
if (!uris.isEmpty()) {
_softDeleteDataMetadata(userId, uris);
}
}
}
} catch (Exception e) {
log.error("Failed deleting metadatas", e);
throw new UserMetadataServiceException("Failed deleting metadatas", e);
}
}
/**
* delete Definition Metadatas.
*
* @param names names to delete
*/
@SuppressWarnings("checkstyle:methodname")
private void _deleteDefinitionMetadata(
@Nullable final List names
) {
if (names != null && !names.isEmpty()) {
final SqlParameterValue[] aNames = names.stream().filter(name -> !name.isPartitionDefinition())
.map(n -> new SqlParameterValue(Types.VARCHAR, n))
.toArray(SqlParameterValue[]::new);
final SqlParameterValue[] aPartitionNames = names.stream().filter(QualifiedName::isPartitionDefinition)
.map(n -> new SqlParameterValue(Types.VARCHAR, n))
.toArray(SqlParameterValue[]::new);
if (aNames.length > 0) {
final List paramVariables = Arrays.stream(aNames).map(s -> "?").collect(Collectors.toList());
jdbcTemplate.update(
String.format(SQL.DELETE_DEFINITION_METADATA, Joiner.on(",").skipNulls().join(paramVariables)),
(Object[]) aNames);
}
if (aPartitionNames.length > 0) {
final List paramVariables =
Arrays.stream(aPartitionNames).map(s -> "?").collect(Collectors.toList());
jdbcTemplate.update(
String.format(SQL.DELETE_PARTITION_DEFINITION_METADATA,
Joiner.on(",").skipNulls().join(paramVariables)), (Object[]) aPartitionNames);
}
}
}
/**
* soft Delete Data Metadatas.
*
* @param userId user id
* @param uris uri list
*/
@SuppressWarnings("checkstyle:methodname")
private void _softDeleteDataMetadata(final String userId,
@Nullable final List uris) {
if (uris != null && !uris.isEmpty()) {
final List paramVariables = uris.stream().map(s -> "?").collect(Collectors.toList());
final String[] aUris = uris.toArray(new String[0]);
final String paramString = Joiner.on(",").skipNulls().join(paramVariables);
final List ids = jdbcTemplate
.query(String.format(SQL.GET_DATA_METADATA_IDS, paramString), aUris, (rs, rowNum) -> rs.getLong("id"));
if (!ids.isEmpty()) {
final List idParamVariables = ids.stream().map(s -> "?").collect(Collectors.toList());
final Long[] aIds = ids.toArray(new Long[0]);
final String idParamString = Joiner.on(",").skipNulls().join(idParamVariables);
final List dupIds = jdbcTemplate
.query(String.format(SQL.GET_DATA_METADATA_DELETE_BY_IDS, idParamString), aIds,
(rs, rowNum) -> rs.getLong("id"));
if (!dupIds.isEmpty()) {
ids.removeAll(dupIds);
}
final List