com.devicehive.dao.riak.UserDaoRiakImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.devicehive.dao.riak.UserDaoRiakImpl.java

Source

package com.devicehive.dao.riak;

/*
 * #%L
 * DeviceHive Dao Riak Implementation
 * %%
 * Copyright (C) 2016 DataArt
 * %%
 * Licensed 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.
 * #L%
 */
import com.basho.riak.client.api.commands.kv.DeleteValue;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.StoreValue;
import com.basho.riak.client.api.commands.mapreduce.BucketMapReduce;
import com.basho.riak.client.api.commands.mapreduce.MapReduce;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import com.devicehive.dao.DeviceDao;
import com.devicehive.dao.NetworkDao;
import com.devicehive.dao.UserDao;
import com.devicehive.dao.riak.model.RiakUser;
import com.devicehive.exceptions.HivePersistenceLayerException;
import com.devicehive.model.enums.UserRole;
import com.devicehive.model.enums.UserStatus;
import com.devicehive.vo.DeviceVO;
import com.devicehive.vo.NetworkVO;
import com.devicehive.vo.UserVO;
import com.devicehive.vo.UserWithNetworkVO;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserDaoRiakImpl extends RiakGenericDao implements UserDao {

    private static final Namespace USER_NS = new Namespace("user");

    private static final Location COUNTERS_LOCATION = new Location(new Namespace("counters", "dh_counters"),
            "userCounter");

    @Autowired
    private UserNetworkDaoRiakImpl userNetworkDao;

    @Autowired
    private NetworkDao networkDao;

    @Autowired
    private NetworkDeviceDaoRiakImpl networkDeviceDao;

    @Autowired
    private DeviceDao deviceDao;

    public UserDaoRiakImpl() {
    }

    @PostConstruct
    public void init() {
        ((NetworkDaoRiakImpl) networkDao).setUserDao(this);
    }

    @Override
    public Optional<UserVO> findByName(String name) {
        RiakUser riakUser = findBySecondaryIndex("login", name, USER_NS, RiakUser.class);
        RiakUser.convertToVo(riakUser);
        return Optional.ofNullable(RiakUser.convertToVo(riakUser));
    }

    @Override
    public UserVO findByGoogleName(String name) {
        RiakUser riakUser = findBySecondaryIndex("googleLogin", name, USER_NS, RiakUser.class);
        RiakUser.convertToVo(riakUser);
        return RiakUser.convertToVo(riakUser);
    }

    @Override
    public UserVO findByFacebookName(String name) {
        RiakUser riakUser = findBySecondaryIndex("facebookLogin", name, USER_NS, RiakUser.class);
        RiakUser.convertToVo(riakUser);
        return RiakUser.convertToVo(riakUser);
    }

    @Override
    public UserVO findByGithubName(String name) {
        RiakUser riakUser = findBySecondaryIndex("githubLogin", name, USER_NS, RiakUser.class);
        RiakUser.convertToVo(riakUser);
        return RiakUser.convertToVo(riakUser);
    }

    @Override
    public Optional<UserVO> findByIdentityName(String login, String googleLogin, String facebookLogin,
            String githubLogin) {
        UserVO userToCheck;
        userToCheck = findByGoogleName(googleLogin);
        if (userToCheck != null) {
            if (doesUserAlreadyExist(userToCheck, login)) {
                return Optional.of(userToCheck);
            }
        }

        userToCheck = findByFacebookName(facebookLogin);
        if (userToCheck != null) {
            if (doesUserAlreadyExist(userToCheck, login)) {
                return Optional.of(userToCheck);
            }
        }

        userToCheck = findByGithubName(githubLogin);
        if (userToCheck != null) {
            if (doesUserAlreadyExist(userToCheck, login)) {
                return Optional.of(userToCheck);
            }
        }

        return Optional.empty();
    }

    @Override
    public long hasAccessToNetwork(UserVO user, NetworkVO network) {
        Set<Long> networks = userNetworkDao.findNetworksForUser(user.getId());
        if (networks != null && networks.contains(network.getId())) {
            return 1L;
        } else {
            return 0L;
        }
    }

    @Override
    public long hasAccessToDevice(UserVO user, String deviceGuid) {
        Set<Long> networkIds = userNetworkDao.findNetworksForUser(user.getId());
        for (Long networkId : networkIds) {
            Set<DeviceVO> devices = networkDeviceDao.findDevicesForNetwork(networkId).stream()
                    .map(deviceDao::findByUUID).collect(Collectors.toSet());
            if (devices != null) {
                long guidCount = devices.stream().map(DeviceVO::getGuid).filter(g -> g.equals(deviceGuid)).count();
                if (guidCount > 0) {
                    return guidCount;
                }
            }
        }
        return 0L;
    }

    @Override
    public UserWithNetworkVO getWithNetworksById(long id) {
        UserVO user = find(id);
        if (user == null) {
            return null;
        }

        Set<Long> networkIds = userNetworkDao.findNetworksForUser(id);
        UserWithNetworkVO userWithNetworkVO = UserWithNetworkVO.fromUserVO(user);
        if (networkIds != null) {
            //TODO [rafa] [implement bulk fetch method here]
            Set<NetworkVO> networks = new HashSet<>();
            for (Long networkId : networkIds) {
                NetworkVO network = networkDao.find(networkId);
                networks.add(network);
            }
            userWithNetworkVO.setNetworks(networks);
        }
        return userWithNetworkVO;
    }

    @Override
    public int deleteById(long id) {
        Location location = new Location(USER_NS, String.valueOf(id));
        DeleteValue deleteOp = new DeleteValue.Builder(location).build();
        try {
            client.execute(deleteOp);
            return 1;
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Cannot delete by id", e);
        }
    }

    @Override
    public UserVO find(Long id) {
        try {
            Location location = new Location(USER_NS, String.valueOf(id));
            FetchValue fetchOp = new FetchValue.Builder(location)
                    .withOption(quorum.getReadQuorumOption(), quorum.getReadQuorum()).build();
            RiakUser riakUser = getOrNull(client.execute(fetchOp), RiakUser.class);
            return RiakUser.convertToVo(riakUser);
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Cannot find by id", e);
        }
    }

    @Override
    public void persist(UserVO user) {
        merge(user);
    }

    @Override
    public UserVO merge(UserVO user) {
        RiakUser entity = RiakUser.convertToEntity(user);
        try {
            if (entity.getId() == null) {
                entity.setId(getId(COUNTERS_LOCATION));
            }
            Location location = new Location(USER_NS, String.valueOf(entity.getId()));
            StoreValue storeOp = new StoreValue.Builder(entity).withLocation(location)
                    .withOption(quorum.getWriteQuorumOption(), quorum.getWriteQuorum()).build();
            client.execute(storeOp);
            user.setId(entity.getId());
            return user;
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Cannot merge user.", e);
        }
    }

    @Override
    public void unassignNetwork(@NotNull UserVO existingUser, @NotNull long networkId) {
        userNetworkDao.delete(existingUser.getId(), networkId);
    }

    @Override
    public List<UserVO> list(String login, String loginPattern, Integer role, Integer status, String sortField,
            Boolean isSortOrderAsc, Integer take, Integer skip) {

        BucketMapReduce.Builder builder = new BucketMapReduce.Builder().withNamespace(USER_NS);
        addMapValues(builder);
        if (login != null) {
            addReduceFilter(builder, "login", FilterOperator.EQUAL, login);
        } else if (loginPattern != null) {
            loginPattern = loginPattern.replace("%", "");
            addReduceFilter(builder, "login", FilterOperator.REGEX, loginPattern);
        }
        if (role != null) {
            String roleString = UserRole.getValueForIndex(role).name();
            addReduceFilter(builder, "role", FilterOperator.EQUAL, roleString);
        }
        if (status != null) {
            String statusString = UserStatus.getValueForIndex(status).name();
            addReduceFilter(builder, "status", FilterOperator.EQUAL, statusString);
        }

        addReduceSort(builder, sortField, isSortOrderAsc);
        addReducePaging(builder, true, take, skip);
        try {
            MapReduce.Response response = client.execute(builder.build());
            Collection<RiakUser> users = response.getResultsFromAllPhases(RiakUser.class);
            return users.stream().map(RiakUser::convertToVo).collect(Collectors.toList());
        } catch (InterruptedException | ExecutionException e) {
            throw new HivePersistenceLayerException("Cannot execute search user.", e);
        }
    }

    private boolean doesUserAlreadyExist(UserVO user, String login) {
        return (!user.getLogin().equals(login) && user.getStatus() != UserStatus.DELETED);
    }
}