org.apache.rya.mongodb.dao.SimpleMongoDBStorageStrategy.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.rya.mongodb.dao.SimpleMongoDBStorageStrategy.java

Source

/*
 * 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.rya.mongodb.dao;

import static org.openrdf.model.vocabulary.XMLSchema.ANYURI;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.apache.rya.api.domain.RyaStatement;
import org.apache.rya.api.domain.RyaType;
import org.apache.rya.api.domain.RyaURI;
import org.apache.rya.api.domain.StatementMetadata;
import org.apache.rya.api.persist.query.RyaQuery;
import org.apache.rya.mongodb.document.visibility.DocumentVisibility;
import org.apache.rya.mongodb.document.visibility.DocumentVisibilityAdapter;
import org.apache.rya.mongodb.document.visibility.DocumentVisibilityAdapter.MalformedDocumentVisibilityException;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.model.vocabulary.XMLSchema;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;

/**
 * Defines how {@link RyaStatement}s are stored in MongoDB.
 */
public class SimpleMongoDBStorageStrategy implements MongoDBStorageStrategy<RyaStatement> {
    private static final Logger LOG = Logger.getLogger(SimpleMongoDBStorageStrategy.class);

    public static final String ID = "_id";
    public static final String OBJECT_TYPE = "objectType";
    public static final String OBJECT_TYPE_VALUE = XMLSchema.ANYURI.stringValue();
    public static final String CONTEXT = "context";
    public static final String PREDICATE = "predicate";
    public static final String PREDICATE_HASH = "predicate_hash";
    public static final String OBJECT = "object";
    public static final String OBJECT_HASH = "object_hash";
    public static final String SUBJECT = "subject";
    public static final String SUBJECT_HASH = "subject_hash";
    public static final String TIMESTAMP = "insertTimestamp";
    public static final String STATEMENT_METADATA = "statementMetadata";
    public static final String DOCUMENT_VISIBILITY = "documentVisibility";

    protected ValueFactoryImpl factory = new ValueFactoryImpl();

    @Override
    public void createIndices(final DBCollection coll) {
        BasicDBObject doc = new BasicDBObject();
        doc.put(SUBJECT_HASH, 1);
        doc.put(PREDICATE_HASH, 1);
        doc.put(OBJECT_HASH, 1);
        doc.put(OBJECT_TYPE, 1);
        coll.createIndex(doc);
        doc = new BasicDBObject(PREDICATE_HASH, 1);
        doc.put(OBJECT_HASH, 1);
        doc.put(OBJECT_TYPE, 1);
        coll.createIndex(doc);
        doc = new BasicDBObject(OBJECT_HASH, 1);
        doc.put(OBJECT_TYPE, 1);
        doc.put(SUBJECT_HASH, 1);
        coll.createIndex(doc);
    }

    @Override
    public DBObject getQuery(final RyaStatement stmt) {
        final RyaURI subject = stmt.getSubject();
        final RyaURI predicate = stmt.getPredicate();
        final RyaType object = stmt.getObject();
        final RyaURI context = stmt.getContext();
        final BasicDBObject query = new BasicDBObject();
        if (subject != null) {
            query.append(SUBJECT_HASH, DigestUtils.sha256Hex(subject.getData()));
        }
        if (object != null) {
            query.append(OBJECT_HASH, DigestUtils.sha256Hex(object.getData()));
            query.append(OBJECT_TYPE, object.getDataType().toString());
        }
        if (predicate != null) {
            query.append(PREDICATE_HASH, DigestUtils.sha256Hex(predicate.getData()));
        }
        if (context != null) {
            query.append(CONTEXT, context.getData());
        }
        return query;
    }

    @Override
    public RyaStatement deserializeDBObject(final DBObject queryResult) {
        final Map<?, ?> result = queryResult.toMap();
        final String subject = (String) result.get(SUBJECT);
        final String object = (String) result.get(OBJECT);
        final String objectType = (String) result.get(OBJECT_TYPE);
        final String predicate = (String) result.get(PREDICATE);
        final String context = (String) result.get(CONTEXT);
        DocumentVisibility documentVisibility = null;
        try {
            documentVisibility = DocumentVisibilityAdapter.toDocumentVisibility(queryResult);
        } catch (final MalformedDocumentVisibilityException e) {
            LOG.error("Unable to convert document visibility");
        }
        final Long timestamp = (Long) result.get(TIMESTAMP);
        final String statementMetadata = (String) result.get(STATEMENT_METADATA);
        RyaType objectRya = null;
        if (objectType.equalsIgnoreCase(ANYURI.stringValue())) {
            objectRya = new RyaURI(object);
        } else {
            objectRya = new RyaType(factory.createURI(objectType), object);
        }

        final RyaStatement statement;
        if (!context.isEmpty()) {
            statement = new RyaStatement(new RyaURI(subject), new RyaURI(predicate), objectRya,
                    new RyaURI(context));
        } else {
            statement = new RyaStatement(new RyaURI(subject), new RyaURI(predicate), objectRya);
        }

        statement.setColumnVisibility(documentVisibility.flatten());
        if (timestamp != null) {
            statement.setTimestamp(timestamp);
        }
        if (statementMetadata != null) {
            try {
                final StatementMetadata metadata = new StatementMetadata(statementMetadata);
                statement.setStatementMetadata(metadata);
            } catch (final Exception ex) {
                LOG.debug("Error deserializing metadata for statement", ex);
            }
        }
        return statement;
    }

    @Override
    public DBObject serialize(final RyaStatement statement) {
        return serializeInternal(statement);
    }

    public BasicDBObject serializeInternal(final RyaStatement statement) {
        String context = "";
        if (statement.getContext() != null) {
            context = statement.getContext().getData();
        }
        final String id = statement.getSubject().getData() + " " + statement.getPredicate().getData() + " "
                + statement.getObject().getData() + " " + context;
        byte[] bytes = id.getBytes(StandardCharsets.UTF_8);
        try {
            final MessageDigest digest = MessageDigest.getInstance("SHA-1");
            bytes = digest.digest(bytes);
        } catch (final NoSuchAlgorithmException e) {
            LOG.error("Unable to perform SHA-1 on the ID, defaulting to raw bytes.", e);
        }
        if (statement.getMetadata() == null) {
            statement.setStatementMetadata(StatementMetadata.EMPTY_METADATA);
        }
        final BasicDBObject dvObject = DocumentVisibilityAdapter.toDBObject(statement.getColumnVisibility());
        final BasicDBObject doc = new BasicDBObject(ID, new String(Hex.encodeHex(bytes)))
                .append(SUBJECT, statement.getSubject().getData())
                .append(SUBJECT_HASH, DigestUtils.sha256Hex(statement.getSubject().getData()))
                .append(PREDICATE, statement.getPredicate().getData())
                .append(PREDICATE_HASH, DigestUtils.sha256Hex(statement.getPredicate().getData()))
                .append(OBJECT, statement.getObject().getData())
                .append(OBJECT_HASH, DigestUtils.sha256Hex(statement.getObject().getData()))
                .append(OBJECT_TYPE, statement.getObject().getDataType().toString()).append(CONTEXT, context)
                .append(STATEMENT_METADATA, statement.getMetadata().toString())
                .append(DOCUMENT_VISIBILITY, dvObject.get(DOCUMENT_VISIBILITY))
                .append(TIMESTAMP, statement.getTimestamp());
        return doc;
    }

    @Override
    public DBObject getQuery(final RyaQuery ryaQuery) {
        return getQuery(ryaQuery.getQuery());
    }
}