blob: cd55ea37b8bd69c0f5d44ffbfb55079e407d3655 [file] [log] [blame]
/*
* 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.nifi.registry.revision.entity;
import org.apache.nifi.registry.revision.api.EntityModification;
import org.apache.nifi.registry.revision.api.Revision;
import org.apache.nifi.registry.revision.api.RevisionClaim;
import org.apache.nifi.registry.revision.api.RevisionManager;
import org.apache.nifi.registry.revision.api.RevisionUpdate;
import org.apache.nifi.registry.revision.standard.StandardRevisionClaim;
import org.apache.nifi.registry.revision.standard.StandardRevisionUpdate;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
/**
* Standard implementation of RevisableEntityService.
*/
public class StandardRevisableEntityService implements RevisableEntityService {
private final RevisionManager revisionManager;
public StandardRevisableEntityService(final RevisionManager revisionManager) {
this.revisionManager = revisionManager;
}
@Override
public <T extends RevisableEntity> T create(final T requestEntity, final String creatorIdentity, final Supplier<T> createEntity) {
if (requestEntity == null) {
throw new IllegalArgumentException("Request entity is required");
}
if (requestEntity.getRevision() == null || requestEntity.getRevision().getVersion() == null) {
throw new IllegalArgumentException("Revision info is required");
}
if (requestEntity.getRevision().getVersion() != 0) {
throw new IllegalArgumentException("A revision version of 0 must be specified when creating a new entity");
}
if (creatorIdentity == null || creatorIdentity.trim().isEmpty()) {
throw new IllegalArgumentException("Creator identity is required");
}
return createOrUpdate(requestEntity, creatorIdentity, createEntity);
}
@Override
public <T extends RevisableEntity> T get(final Supplier<T> getEntity) {
final T entity = getEntity.get();
if (entity != null) {
populateRevision(entity);
}
return entity;
}
@Override
public <T extends RevisableEntity> List<T> getEntities(final Supplier<List<T>> getEntities) {
final List<T> entities = getEntities.get();
populateRevisions(entities);
return entities;
}
@Override
public <T extends RevisableEntity> T update(final T requestEntity, final String updaterIdentity, final Supplier<T> updateEntity) {
if (requestEntity == null) {
throw new IllegalArgumentException("Request entity is required");
}
if (requestEntity.getRevision() == null || requestEntity.getRevision().getVersion() == null) {
throw new IllegalArgumentException("Revision info is required");
}
if (updaterIdentity == null || updaterIdentity.trim().isEmpty()) {
throw new IllegalArgumentException("Updater identity is required");
}
return createOrUpdate(requestEntity, updaterIdentity, updateEntity);
}
@Override
public <T extends RevisableEntity> T delete(final String entityIdentifier, final RevisionInfo revisionInfo, final Supplier<T> deleteEntity) {
if (entityIdentifier == null || entityIdentifier.trim().isEmpty()) {
throw new IllegalArgumentException("Entity identifier is required");
}
if (revisionInfo == null || revisionInfo.getVersion() == null) {
throw new IllegalArgumentException("Revision info is required");
}
final Revision revision = createRevision(entityIdentifier, revisionInfo);
final RevisionClaim claim = new StandardRevisionClaim(revision);
return revisionManager.deleteRevision(claim, () -> deleteEntity.get());
}
private <T extends RevisableEntity> T createOrUpdate(final T requestEntity, final String userIdentity, final Supplier<T> updateOrCreateEntity) {
final Revision revision = createRevision(requestEntity.getIdentifier(), requestEntity.getRevision());
final RevisionClaim claim = new StandardRevisionClaim(revision);
final RevisionUpdate<T> revisionUpdate = revisionManager.updateRevision(claim, () -> {
final T updatedEntity = updateOrCreateEntity.get();
final Revision updatedRevision = revision.incrementRevision(revision.getClientId());
final EntityModification entityModification = new EntityModification(updatedRevision, userIdentity);
final RevisionInfo updatedRevisionInfo = createRevisionInfo(updatedRevision, entityModification);
updatedEntity.setRevision(updatedRevisionInfo);
return new StandardRevisionUpdate<>(updatedEntity, entityModification);
});
return revisionUpdate.getEntity();
}
private <T extends RevisableEntity> void populateRevisions(final Collection<T> revisableEntities) {
if (revisableEntities == null) {
return;
}
revisableEntities.forEach(e -> {
populateRevision(e);
});
}
private void populateRevision(final RevisableEntity e) {
if (e == null) {
return;
}
final Revision entityRevision = revisionManager.getRevision(e.getIdentifier());
final RevisionInfo revisionInfo = createRevisionInfo(entityRevision);
e.setRevision(revisionInfo);
}
private Revision createRevision(final String entityId, final RevisionInfo revisionInfo) {
return new Revision(revisionInfo.getVersion(), revisionInfo.getClientId(), entityId);
}
private RevisionInfo createRevisionInfo(final Revision revision) {
return createRevisionInfo(revision, null);
}
private RevisionInfo createRevisionInfo(final Revision revision, final EntityModification entityModification) {
final RevisionInfo revisionInfo = new RevisionInfo();
revisionInfo.setVersion(revision.getVersion());
revisionInfo.setClientId(revision.getClientId());
if (entityModification != null) {
revisionInfo.setLastModifier(entityModification.getLastModifier());
}
return revisionInfo;
}
}