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

Java tutorial

Introduction

Here is the source code for com.devicehive.dao.riak.NetworkDaoRiakImpl.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.indexes.BinIndexQuery;
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.auth.HivePrincipal;
import com.devicehive.dao.DeviceDao;
import com.devicehive.dao.NetworkDao;
import com.devicehive.dao.UserDao;
import com.devicehive.dao.riak.model.RiakNetwork;
import com.devicehive.dao.riak.model.UserNetwork;
import com.devicehive.exceptions.HivePersistenceLayerException;
import com.devicehive.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Repository
public class NetworkDaoRiakImpl extends RiakGenericDao implements NetworkDao {

    private static final Namespace NETWORK_NS = new Namespace("network");

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

    @Autowired
    private UserNetworkDaoRiakImpl userNetworkDao;

    @Autowired
    private NetworkDeviceDaoRiakImpl networkDeviceDao;

    private DeviceDao deviceDao;
    private UserDao userDao;

    public NetworkDaoRiakImpl() {
    }

    void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    void setDeviceDao(DeviceDao deviceDao) {
        this.deviceDao = deviceDao;
    }

    @Override
    public List<NetworkVO> findByName(String name) {
        if (name == null) {
            return Collections.emptyList();
        }

        BinIndexQuery biq = new BinIndexQuery.Builder(NETWORK_NS, "name", name).build();
        try {
            BinIndexQuery.Response response = client.execute(biq);
            List<RiakNetwork> result = fetchMultiple(response, RiakNetwork.class);
            return result.stream().map(RiakNetwork::convert).collect(Collectors.toList());
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Can't find networks by name", e);
        }
    }

    @Override
    public void persist(@NotNull NetworkVO newNetwork) {
        if (newNetwork.getId() == null) {
            newNetwork.setId(getId(COUNTERS_LOCATION));
        }
        RiakNetwork network = RiakNetwork.convert(newNetwork);

        Location location = new Location(NETWORK_NS, String.valueOf(network.getId()));
        StoreValue storeOp = new StoreValue.Builder(network).withLocation(location)
                .withOption(quorum.getWriteQuorumOption(), quorum.getWriteQuorum()).build();
        try {
            client.execute(storeOp);
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Can't execute store operation on network network", e);
        }
    }

    @Override
    public List<NetworkWithUsersAndDevicesVO> getNetworksByIdsAndUsers(Long idForFiltering, Set<Long> networkdIds,
            Set<Long> permittedNetworks) {
        Set<Long> intersection = networkdIds;
        if (permittedNetworks != null) {
            intersection = networkdIds.stream().filter(permittedNetworks::contains).collect(Collectors.toSet());
        }
        Stream<NetworkWithUsersAndDevicesVO> networkStream = intersection.stream()
                .map(this::findWithUsersAndDevices).filter(Optional::isPresent).map(Optional::get);
        if (idForFiltering != null) {
            networkStream = networkStream
                    .filter(n -> n.getUsers().stream().anyMatch(u -> u.getId().equals(idForFiltering)));
        }
        return networkStream.collect(Collectors.toList());
    }

    @Override
    public int deleteById(long id) {
        Location location = new Location(NETWORK_NS, String.valueOf(id));
        DeleteValue deleteOp = new DeleteValue.Builder(location).build();
        try {
            client.execute(deleteOp);
            return 1;
        } catch (ExecutionException | InterruptedException e) {
            return 0;
        }
    }

    @Override
    public NetworkVO find(@NotNull Long networkId) {
        RiakNetwork vo = get(networkId);
        return RiakNetwork.convert(vo);
    }

    private RiakNetwork get(@NotNull Long networkId) {
        Location location = new Location(NETWORK_NS, String.valueOf(networkId));
        FetchValue fetchOp = new FetchValue.Builder(location)
                .withOption(quorum.getReadQuorumOption(), quorum.getReadQuorum()).build();
        try {
            return getOrNull(client.execute(fetchOp), RiakNetwork.class);
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Can't fetch network by id", e);
        }
    }

    @Override
    public NetworkVO merge(@NotNull NetworkVO network) {
        assert network.getId() != null;

        RiakNetwork existing = get(network.getId());
        existing.setKey(network.getKey());
        existing.setName(network.getName());
        existing.setDescription(network.getDescription());

        Location location = new Location(NETWORK_NS, String.valueOf(network.getId()));
        StoreValue storeOp = new StoreValue.Builder(existing).withLocation(location)
                .withOption(quorum.getWriteQuorumOption(), quorum.getWriteQuorum()).build();
        try {
            client.execute(storeOp);
            return RiakNetwork.convert(existing);
        } catch (ExecutionException | InterruptedException e) {
            throw new HivePersistenceLayerException("Can't execute store operation on network network", e);
        }
    }

    @Override
    public void assignToNetwork(NetworkVO network, UserVO user) {
        assert network != null && network.getId() != null;
        assert user != null && user.getId() != null;

        Set<Long> networksForUser = userNetworkDao.findNetworksForUser(user.getId());
        if (!networksForUser.contains(network.getId())) {
            userNetworkDao.persist(new UserNetwork(user.getId(), network.getId()));
        }
    }

    @Override
    public List<NetworkVO> list(String name, String namePattern, String sortField, boolean isSortOrderAsc,
            Integer take, Integer skip, Optional<HivePrincipal> principalOptional) {
        BucketMapReduce.Builder builder = new BucketMapReduce.Builder().withNamespace(NETWORK_NS);
        addMapValues(builder);

        if (name != null) {
            addReduceFilter(builder, "name", FilterOperator.EQUAL, name);
        } else if (namePattern != null) {
            namePattern = namePattern.replace("%", "");
            addReduceFilter(builder, "name", FilterOperator.REGEX, namePattern);
        }

        if (principalOptional.isPresent()) {
            HivePrincipal principal = principalOptional.get();
            if (principal != null) {
                UserVO user = principal.getUser();

                if (user != null && !user.isAdmin()) {
                    Set<Long> networks = userNetworkDao.findNetworksForUser(user.getId());
                    addReduceFilter(builder, "id", FilterOperator.IN, networks);
                }

                if (principal.getNetworkIds() != null) {
                    Set<Long> ids = principal.getNetworkIds();
                    if (!ids.isEmpty()) {
                        addReduceFilter(builder, "id", FilterOperator.IN, ids);
                    }
                }
            }
        }

        addReduceSort(builder, sortField, isSortOrderAsc);
        addReducePaging(builder, true, take, skip);
        try {
            MapReduce.Response response = client.execute(builder.build());

            return response.getResultsFromAllPhases(RiakNetwork.class).stream().map(RiakNetwork::convert)
                    .collect(Collectors.toList());
        } catch (InterruptedException | ExecutionException e) {
            throw new HivePersistenceLayerException("Cannot get list of networks.", e);
        }
    }

    @Override
    public Optional<NetworkVO> findFirstByName(String name) {
        return findByName(name).stream().findFirst();
    }

    private Optional<NetworkWithUsersAndDevicesVO> findWithUsersAndDevices(long networkId) {
        Optional<NetworkWithUsersAndDevicesVO> result = findWithUsers(networkId);

        if (result.isPresent()) {
            Set<DeviceVO> devices = networkDeviceDao.findDevicesForNetwork(networkId).stream()
                    .map(deviceDao::findByUUID).collect(Collectors.toSet());
            result.get().setDevices(devices);
            return result;
        } else {
            return Optional.empty();
        }
    }

    @Override
    public Optional<NetworkWithUsersAndDevicesVO> findWithUsers(long networkId) {
        NetworkVO networkVO = find(networkId);
        if (networkVO != null) {
            NetworkWithUsersAndDevicesVO vo = new NetworkWithUsersAndDevicesVO(networkVO);
            Set<UserVO> users = userNetworkDao.findUsersInNetwork(networkId).stream().map(userDao::find)
                    .collect(Collectors.toSet());
            vo.setUsers(users);
            return Optional.of(vo);
        } else {
            return Optional.empty();
        }
    }
}