/*******************************************************************************
* 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.ssh.server.jpa;
import com.google.inject.persist.Transactional;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
import org.eclipse.che.api.ssh.server.spi.SshDao;
import org.eclipse.che.api.user.server.event.BeforeUserRemovedEvent;
import org.eclipse.che.core.db.cascade.CascadeEventSubscriber;
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import java.util.List;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
/**
* JPA based implementation of {@link SshDao}.
*
* @author Mihail Kuznyetsov
* @author Yevhenii Voevodin
*/
@Singleton
public class JpaSshDao implements SshDao {
@Inject
private Provider<EntityManager> managerProvider;
@Override
public void create(SshPairImpl sshPair) throws ServerException, ConflictException {
requireNonNull(sshPair);
try {
doCreate(sshPair);
} catch (DuplicateKeyException e) {
throw new ConflictException(format("Ssh pair with service '%s' and name '%s' already exists",
sshPair.getService(),
sshPair.getName()));
} catch (RuntimeException e) {
throw new ServerException(e);
}
}
@Override
@Transactional
public List<SshPairImpl> get(String owner, String service) throws ServerException {
requireNonNull(owner);
requireNonNull(service);
try {
return managerProvider.get()
.createNamedQuery("SshKeyPair.getByOwnerAndService", SshPairImpl.class)
.setParameter("owner", owner)
.setParameter("service", service)
.getResultList();
} catch (RuntimeException e) {
throw new ServerException(e.getLocalizedMessage(), e);
}
}
@Override
@Transactional
public SshPairImpl get(String owner, String service, String name) throws ServerException, NotFoundException {
requireNonNull(owner);
requireNonNull(service);
requireNonNull(name);
try {
SshPairImpl result = managerProvider.get().find(SshPairImpl.class, new SshPairPrimaryKey(owner, service, name));
if (result == null) {
throw new NotFoundException(format("Ssh pair with service '%s' and name '%s' was not found.", service, name));
}
return result;
} catch (RuntimeException e) {
throw new ServerException(e.getLocalizedMessage(), e);
}
}
@Override
public void remove(String owner, String service, String name) throws ServerException, NotFoundException {
requireNonNull(owner);
requireNonNull(service);
requireNonNull(name);
try {
doRemove(owner, service, name);
} catch (RuntimeException e) {
throw new ServerException(e);
}
}
@Override
@Transactional
public List<SshPairImpl> get(String owner) throws ServerException {
requireNonNull(owner, "Required non-null owner");
try {
return managerProvider.get()
.createNamedQuery("SshKeyPair.getByOwner", SshPairImpl.class)
.setParameter("owner", owner)
.getResultList();
} catch (RuntimeException x) {
throw new ServerException(x.getLocalizedMessage(), x);
}
}
@Transactional
protected void doCreate(SshPairImpl entity) {
EntityManager manager = managerProvider.get();
manager.persist(entity);
manager.flush();
}
@Transactional
protected void doRemove(String owner, String service, String name) throws NotFoundException {
EntityManager manager = managerProvider.get();
SshPairImpl entity = manager.find(SshPairImpl.class, new SshPairPrimaryKey(owner, service, name));
if (entity == null) {
throw new NotFoundException(format("Ssh pair with service '%s' and name '%s' was not found.", service, name));
}
manager.remove(entity);
manager.flush();
}
@Singleton
public static class RemoveSshKeysBeforeUserRemovedEventSubscriber
extends CascadeEventSubscriber<BeforeUserRemovedEvent> {
@Inject
private SshDao sshDao;
@Inject
private EventService eventService;
@PostConstruct
public void subscribe() {
eventService.subscribe(this, BeforeUserRemovedEvent.class);
}
@PreDestroy
public void unsubscribe() {
eventService.unsubscribe(this, BeforeUserRemovedEvent.class);
}
@Override
public void onCascadeEvent(BeforeUserRemovedEvent event) throws Exception {
for (SshPairImpl sshPair : sshDao.get(event.getUser().getId())) {
sshDao.remove(sshPair.getOwner(), sshPair.getService(), sshPair.getName());
}
}
}
}