All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.telicent.smart.cache.sources.kafka.serializers.RdfPayloadDeserializer Maven / Gradle / Ivy

There is a newer version: 0.25.1
Show newest version
/**
 * Copyright (C) Telicent Ltd
 *
 * 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 io.telicent.smart.cache.sources.kafka.serializers;

import io.telicent.smart.cache.payloads.RdfPayload;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.rdfpatch.RDFPatchOps;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.WebContent;
import org.apache.kafka.common.header.Headers;
import org.apache.kafka.common.serialization.Deserializer;

import java.io.ByteArrayInputStream;
import java.util.Map;

/**
 * An RDF Payload deserialiser that can cope with both RDF Dataset and RDF Patch format events.  Which format is used is
 * dependent on the {@code Content-Type} header of the event.  If no such header is present then an RDF Dataset is
 * assumed to be the default.
 */
public class RdfPayloadDeserializer extends AbstractRdfSerdes implements Deserializer {

    /**
     * A Kafka configuration key that can be used to configure the deserialiser to eagerly parse the raw data from Kafka
     * rather than delaying parsing to later
     */
    public static final String EAGER_PARSING_CONFIG_KEY = "rdf.payload.parsing.eager";
    private boolean eagerParsing = false;
    private final DatasetGraphDeserializer dsgDeserializer;

    /**
     * Creates a new deserializer
     */
    public RdfPayloadDeserializer() {
        this(Lang.NQUADS);
    }

    /**
     * Creates a new deserializer
     *
     * @param defaultLang Default RDF language to use
     */
    public RdfPayloadDeserializer(Lang defaultLang) {
        super(defaultLang);
        this.dsgDeserializer = new DatasetGraphDeserializer(defaultLang);
    }

    private RdfPayload deserializeInternal(String topic, Headers headers, byte[] data) {
        if (data == null) {
            return null;
        }

        String contentType = findContentType(headers);

        // If eager parsing is not in use create a lazy payload that will be deserialised later
        // To ensure it honours our configured default language in this case we inject a Content-Type header if one
        // wasn't explicitly present
        if (!this.eagerParsing) {
            return RdfPayload.of(contentType != null ? contentType :
                                 this.dsgDeserializer.defaultLang.getContentType().getContentTypeStr(), data);
        }

        if (StringUtils.isBlank(contentType)) {
            // Assume RDF Dataset in our default language
            return RdfPayload.of(this.dsgDeserializer.deserialize(topic, headers, data));
        }

        if (StringUtils.equalsIgnoreCase(contentType, WebContent.ctPatch.getContentTypeStr())) {
            return RdfPayload.of(RDFPatchOps.read(new ByteArrayInputStream(data)));
        } else if (StringUtils.equalsIgnoreCase(contentType, WebContent.ctPatchThrift.getContentTypeStr())) {
            return RdfPayload.of(RDFPatchOps.readBinary(new ByteArrayInputStream(data)));
        } else {
            // Assume an RDF Dataset
            return RdfPayload.of(this.dsgDeserializer.deserialize(topic, headers, data));
        }
    }

    @Override
    public void configure(Map configs, boolean isKey) {
        try {
            this.eagerParsing = StringUtils.equalsIgnoreCase((String) configs.get(EAGER_PARSING_CONFIG_KEY),
                                                             Boolean.TRUE.toString());
        } catch (ClassCastException e) {
            this.eagerParsing = false;
        }
    }

    @Override
    public RdfPayload deserialize(String topic, byte[] data) {
        return deserializeInternal(topic, null, data);
    }

    @Override
    public RdfPayload deserialize(String topic, Headers headers, byte[] data) {
        return deserializeInternal(topic, headers, data);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy