/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.machine.server.jpa; import com.google.inject.persist.Transactional; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.core.db.jpa.DuplicateKeyException; import org.eclipse.che.api.machine.server.exception.SnapshotException; import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl; import org.eclipse.che.api.machine.server.spi.SnapshotDao; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import java.util.Collection; import java.util.List; import static java.lang.String.format; import static java.util.Objects.requireNonNull; /** * JPA based {@link SnapshotDao} implementation. * * @author Yevhenii Voevodin */ @Singleton public class JpaSnapshotDao implements SnapshotDao { @Inject private Provider<EntityManager> managerProvider; @Override @Transactional public SnapshotImpl getSnapshot(String snapshotId) throws NotFoundException, SnapshotException { requireNonNull(snapshotId, "Required non-null snapshotId"); try { final SnapshotImpl snapshot = managerProvider.get().find(SnapshotImpl.class, snapshotId); if (snapshot == null) { throw new NotFoundException(format("Snapshot with id '%s' doesn't exist", snapshotId)); } return snapshot; } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Override @Transactional public SnapshotImpl getSnapshot(String workspaceId, String envName, String machineName) throws NotFoundException, SnapshotException { requireNonNull(workspaceId, "Required non-null workspace id"); requireNonNull(envName, "Required non-null environment name"); requireNonNull(machineName, "Required non-null machine name"); try { return managerProvider.get() .createNamedQuery("Snapshot.getByMachine", SnapshotImpl.class) .setParameter("workspaceId", workspaceId) .setParameter("envName", envName) .setParameter("machineName", machineName) .getSingleResult(); } catch (NoResultException x) { throw new NotFoundException(format("Snapshot for machine '%s:%s:%s' doesn't exist", workspaceId, envName, machineName)); } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Override @Transactional public List<SnapshotImpl> findSnapshots(String workspaceId) throws SnapshotException { requireNonNull(workspaceId, "Required non-null workspace id"); try { return managerProvider.get() .createNamedQuery("Snapshot.findSnapshots", SnapshotImpl.class) .setParameter("workspaceId", workspaceId) .getResultList(); } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Override public void saveSnapshot(SnapshotImpl snapshot) throws SnapshotException { requireNonNull(snapshot, "Required non-null snapshot"); try { doSave(snapshot); } catch (DuplicateKeyException x) { throw new SnapshotException(format("Snapshot with id '%s' or for machine '%s:%s:%s' already exists", snapshot.getId(), snapshot.getWorkspaceId(), snapshot.getEnvName(), snapshot.getMachineName())); } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Override public void removeSnapshot(String snapshotId) throws NotFoundException, SnapshotException { requireNonNull(snapshotId, "Required non-null snapshot id"); try { doRemove(snapshotId); } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Override public List<SnapshotImpl> replaceSnapshots(String workspaceId, String envName, Collection<? extends SnapshotImpl> newSnapshots) throws SnapshotException { requireNonNull(workspaceId, "Required non-null workspace id"); requireNonNull(envName, "Required non-null environment name"); requireNonNull(newSnapshots, "Required non-null new snapshots"); try { return doReplaceSnapshots(workspaceId, envName, newSnapshots); } catch (RuntimeException x) { throw new SnapshotException(x.getLocalizedMessage(), x); } } @Transactional protected void doSave(SnapshotImpl snapshot) { managerProvider.get().persist(snapshot); } @Transactional protected void doRemove(String snapshotId) throws NotFoundException { final EntityManager manager = managerProvider.get(); final SnapshotImpl snapshot = manager.find(SnapshotImpl.class, snapshotId); if (snapshot == null) { throw new NotFoundException(format("Snapshot with id '%s' doesn't exist", snapshotId)); } manager.remove(snapshot); } @Transactional protected List<SnapshotImpl> doReplaceSnapshots(String workspaceId, String envName, Collection<? extends SnapshotImpl> newSnapshots) { final EntityManager manager = managerProvider.get(); final List<SnapshotImpl> existing = manager.createNamedQuery("Snapshot.findByWorkspaceAndEnvironment", SnapshotImpl.class) .setParameter("workspaceId", workspaceId) .setParameter("envName", envName) .getResultList(); existing.forEach(manager::remove); manager.flush(); newSnapshots.forEach(manager::persist); return existing; } }