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.
/*
* 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.pulsar.client.impl.schema;
import static org.apache.pulsar.shade.com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.pulsar.shade.org.apache.avro.Schema.Type.RECORD;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.shade.org.apache.avro.reflect.ReflectData;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.client.api.SchemaSerializationException;
import org.apache.pulsar.client.api.schema.GenericRecord;
import org.apache.pulsar.client.api.schema.SchemaDefinition;
import org.apache.pulsar.client.api.schema.SchemaInfoProvider;
import org.apache.pulsar.client.impl.schema.generic.GenericProtobufNativeSchema;
import org.apache.pulsar.client.impl.schema.generic.GenericSchemaImpl;
import org.apache.pulsar.client.impl.schema.util.SchemaUtil;
import org.apache.pulsar.common.protocol.schema.BytesSchemaVersion;
import org.apache.pulsar.common.protocol.schema.SchemaVersion;
import org.apache.pulsar.common.schema.KeyValue;
import org.apache.pulsar.common.schema.SchemaInfo;
import org.apache.pulsar.common.schema.SchemaType;
/**
* Auto detect schema, returns only GenericRecord instances.
*/
@Slf4j
public class AutoConsumeSchema implements Schema {
private final ConcurrentMap> schemaMap = initSchemaMap();
private String topicName;
private String componentName;
private SchemaInfoProvider schemaInfoProvider;
public static final SchemaInfo SCHEMA_INFO = SchemaInfoImpl.builder()
.name("AutoConsume")
.type(SchemaType.AUTO_CONSUME)
.schema(new byte[0])
.build();
private ConcurrentMap> initSchemaMap() {
ConcurrentMap> schemaMap = new ConcurrentHashMap<>();
// The Schema.BYTES will not be uploaded to the broker and store in the schema storage,
// if the schema version in the message metadata is empty byte[], it means its schema is Schema.BYTES.
schemaMap.put(BytesSchemaVersion.of(new byte[0]), Schema.BYTES);
return schemaMap;
}
public void setSchema(SchemaVersion schemaVersion, Schema> schema) {
schemaMap.put(schemaVersion, schema);
}
public void setSchema(Schema> schema) {
schemaMap.put(SchemaVersion.Latest, schema);
}
private void ensureSchemaInitialized(SchemaVersion schemaVersion) {
checkState(schemaMap.containsKey(schemaVersion),
"Schema version " + schemaVersion + " is not initialized before used");
}
@Override
public void validate(byte[] message) {
ensureSchemaInitialized(SchemaVersion.Latest);
schemaMap.get(SchemaVersion.Latest).validate(message);
}
public void validate(byte[] message, byte[] schemaVersion) {
SchemaVersion sv = getSchemaVersion(schemaVersion);
ensureSchemaInitialized(sv);
schemaMap.get(sv).validate(message);
}
@Override
public byte[] encode(GenericRecord message) {
throw new UnsupportedOperationException("AutoConsumeSchema is not intended to be used for encoding");
}
@Override
public boolean supportSchemaVersioning() {
return true;
}
public Schema> atSchemaVersion(byte[] schemaVersion) {
SchemaVersion sv = getSchemaVersion(schemaVersion);
fetchSchemaIfNeeded(sv);
ensureSchemaInitialized(sv);
Schema> topicVersionedSchema = schemaMap.get(sv);
if (topicVersionedSchema.supportSchemaVersioning() && topicVersionedSchema instanceof AbstractSchema) {
return ((AbstractSchema>) topicVersionedSchema).atSchemaVersion(schemaVersion);
} else {
return topicVersionedSchema;
}
}
@Override
public GenericRecord decode(byte[] bytes, byte[] schemaVersion) {
SchemaVersion sv = getSchemaVersion(schemaVersion);
fetchSchemaIfNeeded(sv);
ensureSchemaInitialized(sv);
return adapt(schemaMap.get(sv).decode(bytes, schemaVersion), schemaVersion);
}
@Override
public GenericRecord decode(ByteBuffer buffer, byte[] schemaVersion) {
SchemaVersion sv = getSchemaVersion(schemaVersion);
fetchSchemaIfNeeded(sv);
ensureSchemaInitialized(sv);
return adapt(schemaMap.get(sv).decode(buffer, schemaVersion), schemaVersion);
}
@Override
public void setSchemaInfoProvider(SchemaInfoProvider schemaInfoProvider) {
this.schemaInfoProvider = schemaInfoProvider;
for (Schema> schema : schemaMap.values()) {
schema.setSchemaInfoProvider(schemaInfoProvider);
}
}
@Override
public SchemaInfo getSchemaInfo() {
if (!schemaMap.containsKey(SchemaVersion.Latest)) {
return null;
}
return schemaMap.get(SchemaVersion.Latest).getSchemaInfo();
}
public SchemaInfo getSchemaInfo(byte[] schemaVersion) {
SchemaVersion sv = getSchemaVersion(schemaVersion);
if (schemaMap.containsKey(sv)) {
return schemaMap.get(sv).getSchemaInfo();
}
return null;
}
@Override
public void configureSchemaInfo(String topicName,
String componentName,
SchemaInfo schemaInfo) {
this.topicName = topicName;
this.componentName = componentName;
if (schemaInfo != null) {
Schema> genericSchema = generateSchema(schemaInfo);
setSchema(SchemaVersion.Latest, genericSchema);
log.info("Configure {} schema for topic {} : {}",
componentName, topicName, schemaInfo.getSchemaDefinition());
}
}
@Override
public Optional