Search in sources :

Example 16 with Change

use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.

the class BranchTicketService method getJournal.

/**
	 * Returns the journal for the specified ticket.
	 *
	 * @param db
	 * @param ticketId
	 * @return a list of changes
	 */
private List<Change> getJournal(Repository db, long ticketId) {
    RefModel ticketsBranch = getTicketsBranch(db);
    if (ticketsBranch == null) {
        return new ArrayList<Change>();
    }
    if (ticketId <= 0L) {
        return new ArrayList<Change>();
    }
    String journalPath = toTicketPath(ticketId) + "/" + JOURNAL;
    String json = readTicketsFile(db, journalPath);
    if (StringUtils.isEmpty(json)) {
        return new ArrayList<Change>();
    }
    List<Change> list = TicketSerializer.deserializeJournal(json);
    return list;
}
Also used : RefModel(com.gitblit.models.RefModel) ArrayList(java.util.ArrayList) Change(com.gitblit.models.TicketModel.Change)

Example 17 with Change

use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.

the class BranchTicketService method getTickets.

/**
	 * Returns all the tickets in the repository. Querying tickets from the
	 * repository requires deserializing all tickets. This is an  expensive
	 * process and not recommended. Tickets are indexed by Lucene and queries
	 * should be executed against that index.
	 *
	 * @param repository
	 * @param filter
	 *            optional filter to only return matching results
	 * @return a list of tickets
	 */
@Override
public List<TicketModel> getTickets(RepositoryModel repository, TicketFilter filter) {
    List<TicketModel> list = new ArrayList<TicketModel>();
    Repository db = repositoryManager.getRepository(repository.name);
    try {
        RefModel ticketsBranch = getTicketsBranch(db);
        if (ticketsBranch == null) {
            return list;
        }
        // Collect the set of all json files
        List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
        // Deserialize each ticket and optionally filter out unwanted tickets
        for (PathModel path : paths) {
            String name = path.name.substring(path.name.lastIndexOf('/') + 1);
            if (!JOURNAL.equals(name)) {
                continue;
            }
            String json = readTicketsFile(db, path.path);
            if (StringUtils.isEmpty(json)) {
                // journal was touched but no changes were written
                continue;
            }
            try {
                // Reconstruct ticketId from the path
                // id/26/326/journal.json
                String tid = path.path.split("/")[2];
                long ticketId = Long.parseLong(tid);
                List<Change> changes = TicketSerializer.deserializeJournal(json);
                if (ArrayUtils.isEmpty(changes)) {
                    log.warn("Empty journal for {}:{}", repository, path.path);
                    continue;
                }
                TicketModel ticket = TicketModel.buildTicket(changes);
                ticket.project = repository.projectPath;
                ticket.repository = repository.name;
                ticket.number = ticketId;
                // add the ticket, conditionally, to the list
                if (filter == null) {
                    list.add(ticket);
                } else {
                    if (filter.accept(ticket)) {
                        list.add(ticket);
                    }
                }
            } catch (Exception e) {
                log.error("failed to deserialize {}/{}\n{}", new Object[] { repository, path.path, e.getMessage() });
                log.error(null, e);
            }
        }
        // sort the tickets by creation
        Collections.sort(list);
        return list;
    } finally {
        db.close();
    }
}
Also used : RefModel(com.gitblit.models.RefModel) ArrayList(java.util.ArrayList) TicketModel(com.gitblit.models.TicketModel) Change(com.gitblit.models.TicketModel.Change) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) IOException(java.io.IOException) Repository(org.eclipse.jgit.lib.Repository) PathModel(com.gitblit.models.PathModel)

Example 18 with Change

use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.

the class RedisTicketService method commitChangeImpl.

/**
	 * Commit a ticket change to the repository.
	 *
	 * @param repository
	 * @param ticketId
	 * @param change
	 * @return true, if the change was committed
	 */
@Override
protected boolean commitChangeImpl(RepositoryModel repository, long ticketId, Change change) {
    Jedis jedis = pool.getResource();
    if (jedis == null) {
        return false;
    }
    try {
        List<Change> changes = getJournal(jedis, repository, ticketId);
        changes.add(change);
        // build a new effective ticket from the changes
        TicketModel ticket = TicketModel.buildTicket(changes);
        String object = TicketSerializer.serialize(ticket);
        String journal = TicketSerializer.serialize(change);
        // atomically store ticket
        Transaction t = jedis.multi();
        t.set(key(repository, KeyType.ticket, ticketId), object);
        t.rpush(key(repository, KeyType.journal, ticketId), journal);
        t.exec();
        log.debug("updated ticket {} in Redis @ {}", "" + ticketId, getUrl());
        return true;
    } catch (JedisException e) {
        log.error("failed to update ticket cache in Redis @ " + getUrl(), e);
        pool.returnBrokenResource(jedis);
        jedis = null;
    } finally {
        if (jedis != null) {
            pool.returnResource(jedis);
        }
    }
    return false;
}
Also used : Jedis(redis.clients.jedis.Jedis) JedisException(redis.clients.jedis.exceptions.JedisException) Transaction(redis.clients.jedis.Transaction) TicketModel(com.gitblit.models.TicketModel) Change(com.gitblit.models.TicketModel.Change)

Example 19 with Change

use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.

the class RedisTicketService method getTickets.

/**
	 * Returns all the tickets in the repository. Querying tickets from the
	 * repository requires deserializing all tickets. This is an  expensive
	 * process and not recommended. Tickets should be indexed by Lucene and
	 * queries should be executed against that index.
	 *
	 * @param repository
	 * @param filter
	 *            optional filter to only return matching results
	 * @return a list of tickets
	 */
@Override
public List<TicketModel> getTickets(RepositoryModel repository, TicketFilter filter) {
    Jedis jedis = pool.getResource();
    List<TicketModel> list = new ArrayList<TicketModel>();
    if (jedis == null) {
        return list;
    }
    try {
        // Deserialize each journal, build the ticket, and optionally filter
        Set<String> keys = jedis.keys(key(repository, KeyType.journal, "*"));
        for (String key : keys) {
            // {repo}:journal:{id}
            String id = key.split(":")[2];
            long ticketId = Long.parseLong(id);
            List<Change> changes = getJournal(jedis, repository, ticketId);
            if (ArrayUtils.isEmpty(changes)) {
                log.warn("Empty journal for {}:{}", repository, ticketId);
                continue;
            }
            TicketModel ticket = TicketModel.buildTicket(changes);
            ticket.project = repository.projectPath;
            ticket.repository = repository.name;
            ticket.number = ticketId;
            // add the ticket, conditionally, to the list
            if (filter == null) {
                list.add(ticket);
            } else {
                if (filter.accept(ticket)) {
                    list.add(ticket);
                }
            }
        }
        // sort the tickets by creation
        Collections.sort(list);
    } catch (JedisException e) {
        log.error("failed to retrieve tickets from Redis @ " + getUrl(), e);
        pool.returnBrokenResource(jedis);
        jedis = null;
    } finally {
        if (jedis != null) {
            pool.returnResource(jedis);
        }
    }
    return list;
}
Also used : Jedis(redis.clients.jedis.Jedis) JedisException(redis.clients.jedis.exceptions.JedisException) ArrayList(java.util.ArrayList) TicketModel(com.gitblit.models.TicketModel) Change(com.gitblit.models.TicketModel.Change)

Example 20 with Change

use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.

the class BranchTicketService method createIndex.

/**
	 * Creates an in-memory index of the ticket change.
	 *
	 * @param changeId
	 * @param change
	 * @return an in-memory index
	 * @throws IOException
	 */
private DirCache createIndex(Repository db, long ticketId, Change change) throws IOException, ClassNotFoundException, NoSuchFieldException {
    String ticketPath = toTicketPath(ticketId);
    DirCache newIndex = DirCache.newInCore();
    DirCacheBuilder builder = newIndex.builder();
    ObjectInserter inserter = db.newObjectInserter();
    Set<String> ignorePaths = new TreeSet<String>();
    try {
        // create/update the journal
        // exclude the attachment content
        List<Change> changes = getJournal(db, ticketId);
        changes.add(change);
        String journal = TicketSerializer.serializeJournal(changes).trim();
        byte[] journalBytes = journal.getBytes(Constants.ENCODING);
        String journalPath = ticketPath + "/" + JOURNAL;
        final DirCacheEntry journalEntry = new DirCacheEntry(journalPath);
        journalEntry.setLength(journalBytes.length);
        journalEntry.setLastModified(change.date.getTime());
        journalEntry.setFileMode(FileMode.REGULAR_FILE);
        journalEntry.setObjectId(inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, journalBytes));
        // add journal to index
        builder.add(journalEntry);
        ignorePaths.add(journalEntry.getPathString());
        // Add any attachments to the index
        if (change.hasAttachments()) {
            for (Attachment attachment : change.attachments) {
                // build a path name for the attachment and mark as ignored
                String path = toAttachmentPath(ticketId, attachment.name);
                ignorePaths.add(path);
                // create an index entry for this attachment
                final DirCacheEntry entry = new DirCacheEntry(path);
                entry.setLength(attachment.content.length);
                entry.setLastModified(change.date.getTime());
                entry.setFileMode(FileMode.REGULAR_FILE);
                // insert object
                entry.setObjectId(inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, attachment.content));
                // add to temporary in-core index
                builder.add(entry);
            }
        }
        for (DirCacheEntry entry : JGitUtils.getTreeEntries(db, BRANCH, ignorePaths)) {
            builder.add(entry);
        }
        // finish the index
        builder.finish();
    } finally {
        inserter.close();
    }
    return newIndex;
}
Also used : DirCache(org.eclipse.jgit.dircache.DirCache) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) TreeSet(java.util.TreeSet) Attachment(com.gitblit.models.TicketModel.Attachment) Change(com.gitblit.models.TicketModel.Change)

Aggregations

Change (com.gitblit.models.TicketModel.Change)45 TicketModel (com.gitblit.models.TicketModel)32 IOException (java.io.IOException)15 Repository (org.eclipse.jgit.lib.Repository)9 Test (org.junit.Test)9 Patchset (com.gitblit.models.TicketModel.Patchset)8 TicketLink (com.gitblit.models.TicketModel.TicketLink)7 ArrayList (java.util.ArrayList)7 RepositoryModel (com.gitblit.models.RepositoryModel)6 UserModel (com.gitblit.models.UserModel)5 RevCommit (org.eclipse.jgit.revwalk.RevCommit)4 Reference (com.gitblit.models.TicketModel.Reference)3 Ref (org.eclipse.jgit.lib.Ref)3 RevWalk (org.eclipse.jgit.revwalk.RevWalk)3 ReceiveCommand (org.eclipse.jgit.transport.ReceiveCommand)3 PatchsetHook (com.gitblit.extensions.PatchsetHook)2 PathChangeModel (com.gitblit.models.PathModel.PathChangeModel)2 RefModel (com.gitblit.models.RefModel)2 Attachment (com.gitblit.models.TicketModel.Attachment)2 Review (com.gitblit.models.TicketModel.Review)2