/* * RHQ Management Platform * Copyright (C) 2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.plugins.drift.mongodb.dao; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import com.google.code.morphia.Morphia; import com.google.code.morphia.dao.BasicDAO; import com.google.code.morphia.query.Query; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.Mongo; import org.bson.types.ObjectId; import org.rhq.core.domain.criteria.DriftChangeSetCriteria; import org.rhq.core.domain.criteria.DriftCriteria; import org.rhq.core.domain.util.PageOrdering; import org.rhq.enterprise.server.plugins.drift.mongodb.entities.MongoDBChangeSet; import org.rhq.enterprise.server.plugins.drift.mongodb.entities.MongoDBChangeSetEntry; import static java.util.Arrays.asList; public class ChangeSetDAO extends BasicDAO<MongoDBChangeSet, ObjectId> { private Morphia morphia; public ChangeSetDAO(Morphia morphia, Mongo mongo, String db) { super(mongo, morphia, db); this.morphia = morphia; } public List<MongoDBChangeSet> findByChangeSetCritiera(DriftChangeSetCriteria criteria) { Query<MongoDBChangeSet> query = createQuery(); if (criteria.getFilterId() != null) { // There is no need to apply any additional filters if the id filter is specified return query.field("id").equal(new ObjectId(criteria.getFilterId())).asList(); } if (criteria.getFilterResourceId() != null) { query.field("resourceId").equal(criteria.getFilterResourceId()); } if (criteria.getFilterDriftDefinitionId() != null) { query.field("driftDefId").equal(criteria.getFilterDriftDefinitionId()); } if (criteria.getFilterVersion() != null) { query.field("version").equal(Integer.parseInt(criteria.getFilterVersion())); } if (criteria.getFilterStartVersion() != null) { query.field("version").greaterThanOrEq(Integer.parseInt(criteria.getFilterStartVersion())); } if (criteria.getFilterEndVersion() != null) { query.field("version").lessThanOrEq(Integer.parseInt(criteria.getFilterEndVersion())); } if (criteria.getFilterCreatedAfter() != null) { query.field("ctime").greaterThanOrEq(criteria.getFilterCreatedAfter()); } if (criteria.getFilterCreatedBefore() != null) { query.field("ctime").lessThan(criteria.getFilterCreatedBefore()); } if (criteria.getFilterDriftPath() != null) { query.field("files.path").equal(Pattern.compile(".*" + criteria.getFilterDriftPath() + ".*")); } if (criteria.getFilterDriftDirectory() != null) { query.field("files.directory").equal(criteria.getFilterDriftDirectory()); } if (criteria.getFilterCategory() != null) { query.field("category").equal(criteria.getFilterCategory()); } if (criteria.getFilterDriftCategories() != null) { query.field("files.category").in(criteria.getFilterDriftCategories()); } if (!criteria.isFetchDrifts()) { query.retrievedFields(false, "files"); } if (criteria.getSortVersion() != null) { if (criteria.getSortVersion() == PageOrdering.ASC) { query.order("version"); } else { query.order("-version"); } } return query.asList(); } public List<MongoDBChangeSet> findByDriftCriteria(DriftCriteria criteria) { Query<MongoDBChangeSet> query = createQuery(); if (criteria.getFilterId() != null) { // TODO use the $slice operator // The slice operator will allow us to return only the requested entry in the // change set document. Morphia does not yet support the $slice operator so // we will hae to drop down to the mongo driver to issue a query. String[] ids = criteria.getFilterId().split(":"); ObjectId changeSetId = new ObjectId(ids[0]); query.field("id").equal(changeSetId); // If the id filter is set, there is no need to process other filters since the id // filter uniquely identifies both the change set and the drift entry. return query.asList(); } if (criteria.getFilterChangeSetId() != null && !criteria.getFilterChangeSetId().isEmpty()) { query.field("id").equal(new ObjectId(criteria.getFilterChangeSetId())); return query.asList(); } if (criteria.getFilterResourceIds() != null && criteria.getFilterResourceIds().length > 0) { query.field("resourceId").in(asList(criteria.getFilterResourceIds())); } if (criteria.getFilterCategories() != null && criteria.getFilterCategories().length > 0) { query.field("files.category").in(asList(criteria.getFilterCategories())); } if (criteria.getFilterStartTime() != null) { query.field("files.ctime").greaterThanOrEq(criteria.getFilterStartTime()); } if (criteria.getFilterEndTime() != null) { query.field("files.ctime").lessThanOrEq(criteria.getFilterEndTime()); } if (criteria.getFilterPath() != null && !criteria.getFilterPath().isEmpty()) { query.field("files.path").equal(criteria.getFilterPath()); } return query.asList(); } public List<MongoDBChangeSetEntry> findEntries(DriftCriteria criteria) { // TODO Add support for driftHandlingModes filter if (criteria.getFilterId() != null) { String[] ids = criteria.getFilterId().split(":"); ObjectId changeSetId = new ObjectId(ids[0]); return asList(findEntryById(changeSetId, ids[1])); } Query<MongoDBChangeSet> query = createQuery(); boolean changeSetsFiltered = false; boolean entriesFiltered = false; ChangeSetEntryFilters filters = new ChangeSetEntryFilters(); if (criteria.getFilterChangeSetId() != null) { query.field("id").equal(new ObjectId(criteria.getFilterChangeSetId())); changeSetsFiltered = true; } if (criteria.getFilterResourceIds().length > 0) { query.field("resourceId").in(asList(criteria.getFilterResourceIds())); changeSetsFiltered = true; } if (criteria.getFilterDriftDefinitionId() != null) { query.field("driftDefId").equal(criteria.getFilterDriftDefinitionId()); changeSetsFiltered = true; } if (criteria.getFilterChangeSetStartVersion() != null) { query.field("version").greaterThanOrEq(criteria.getFilterChangeSetStartVersion()); changeSetsFiltered = true; } if (criteria.getFilterChangeSetEndVersion() != null) { query.field("version").lessThanOrEq(criteria.getFilterChangeSetEndVersion()); changeSetsFiltered = true; } if (criteria.getFilterCategories().length > 0) { query.field("files.category").in(asList(criteria.getFilterCategories())); entriesFiltered = true; filters.add(new CategoryFilter(criteria.getFilterCategories())); } if (criteria.getFilterEndTime() != null) { query.field("files.ctime").lessThanOrEq(criteria.getFilterEndTime()); entriesFiltered = true; filters.add(new CreatedBeforeFilter(criteria.getFilterEndTime())); } if (criteria.getFilterStartTime() != null) { query.field("files.ctime").greaterThanOrEq(criteria.getFilterStartTime()); entriesFiltered = true; filters.add(new CreatedAfterFilter(criteria.getFilterStartTime())); } if (criteria.getFilterPath() != null && !criteria.getFilterPath().isEmpty()) { query.field("files.path").equal(criteria.getFilterPath()); entriesFiltered = true; filters.add(new PathFilter(criteria.getFilterPath())); } if (criteria.getFilterDirectory() != null) { query.field("files.directory").equal(criteria.getFilterDirectory()); entriesFiltered = true; filters.add(new DirectoryFilter(criteria.getFilterDirectory())); } List<MongoDBChangeSetEntry> entries = new ArrayList<MongoDBChangeSetEntry>(); if (changeSetsFiltered && !entriesFiltered) { // If the query only filters on change set fields, we do not need to do any // additional filtering since it was already done by the database. for (MongoDBChangeSet c : query.asList()) { entries.addAll(c.getDrifts()); } } else { for (MongoDBChangeSet c : query.asList()) { for (MongoDBChangeSetEntry e : c.getDrifts()) { if (filters.matchesAll(e)) { entries.add(e); } } } } return entries; } public MongoDBChangeSetEntry findEntryById(ObjectId changeSetId, String entryId) { BasicDBObject query = new BasicDBObject(); query.put("_id", changeSetId); BasicDBObject keys = new BasicDBObject(); keys.put("files", new BasicDBObject().append("$slice", new Integer[] {Integer.valueOf(entryId), 1})); DBObject result = getCollection().findOne(query, keys); if (result == null) { return null; } MongoDBChangeSet changeSet = morphia.fromDBObject(MongoDBChangeSet.class, result); if (!changeSet.getDrifts().isEmpty()) { return changeSet.getDrifts().iterator().next(); } return null; } public void deleteChangeSets(int resourceId, String driftDefName) { deleteByQuery(createQuery() .field("resourceId").equal(resourceId) .field("driftDefName").equal(driftDefName)); } }