/* * 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. */ /* * Copyright 2015 ScyllaDB * * Modified by ScyllaDB */ package org.apache.cassandra.streaming; import java.io.Serializable; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import javax.json.JsonArray; import javax.json.JsonObject; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; /** * Stream session info. */ public final class SessionInfo implements Serializable { public final InetAddress peer; public final int sessionIndex; public final InetAddress connecting; /** Immutable collection of receiving summaries */ public final Collection receivingSummaries; /** Immutable collection of sending summaries*/ public final Collection sendingSummaries; /** Current session state */ public final StreamSession.State state; private final Map receivingFiles; private final Map sendingFiles; static InetAddress address(String val) { try { return InetAddress.getByName(val); } catch (UnknownHostException e) { } return null; } public SessionInfo(InetAddress peer, int sessionIndex, InetAddress connecting, Collection receivingSummaries, Collection sendingSummaries, StreamSession.State state, Map receivingFiles, Map sendingFiles) { this.peer = peer; this.sessionIndex = sessionIndex; this.connecting = connecting; this.receivingSummaries = receivingSummaries; this.sendingSummaries = sendingSummaries; this.receivingFiles = receivingFiles; this.sendingFiles = sendingFiles; this.state = state; } public SessionInfo(String peer, int sessionIndex, String connecting, Collection receivingSummaries, Collection sendingSummaries, String state, Map receivingFiles, Map sendingFiles) { this(address(peer), sessionIndex, address(connecting), receivingSummaries, sendingSummaries, StreamSession.State.valueOf(state), receivingFiles, sendingFiles); } ProgressInfo in; public static SessionInfo fromJsonObject(JsonObject obj) { return new SessionInfo(obj.getString("peer"), obj.getInt("session_index"), obj.getString("connecting"), StreamSummary.fromJsonArr(obj.getJsonArray("receiving_summaries")), StreamSummary.fromJsonArr(obj.getJsonArray("sending_summaries")), obj.getString("state"), ProgressInfo.fromJArrray(obj.getJsonArray("receiving_files")), ProgressInfo.fromJArrray(obj.getJsonArray("sending_files"))); } public static Set fromJsonArr(JsonArray arr) { Set res = new HashSet(); if (arr != null) { for (int i = 0; i < arr.size(); i++) { res.add(fromJsonObject(arr.getJsonObject(i))); } } return res; } public boolean isFailed() { return state == StreamSession.State.FAILED; } /** * Update progress of receiving/sending file. * * @param newProgress new progress info */ public void updateProgress(ProgressInfo newProgress) { assert peer.equals(newProgress.peer); Map currentFiles = newProgress.direction == ProgressInfo.Direction.IN ? receivingFiles : sendingFiles; currentFiles.put(newProgress.fileName, newProgress); } public Collection getReceivingFiles() { return receivingFiles.values(); } public Collection getSendingFiles() { return sendingFiles.values(); } /** * @return total number of files already received. */ public long getTotalFilesReceived() { return getTotalFilesCompleted(receivingFiles.values()); } /** * @return total number of files already sent. */ public long getTotalFilesSent() { return getTotalFilesCompleted(sendingFiles.values()); } /** * @return total size(in bytes) already received. */ public long getTotalSizeReceived() { return getTotalSizeInProgress(receivingFiles.values()); } /** * @return total size(in bytes) already sent. */ public long getTotalSizeSent() { return getTotalSizeInProgress(sendingFiles.values()); } /** * @return total number of files to receive in the session */ public long getTotalFilesToReceive() { return getTotalFiles(receivingSummaries); } /** * @return total number of files to send in the session */ public long getTotalFilesToSend() { return getTotalFiles(sendingSummaries); } /** * @return total size(in bytes) to receive in the session */ public long getTotalSizeToReceive() { return getTotalSizes(receivingSummaries); } /** * @return total size(in bytes) to send in the session */ public long getTotalSizeToSend() { return getTotalSizes(sendingSummaries); } private long getTotalSizeInProgress(Collection files) { long total = 0; for (ProgressInfo file : files) total += file.currentBytes; return total; } private long getTotalFiles(Collection summaries) { long total = 0; for (StreamSummary summary : summaries) total += summary.files; return total; } private long getTotalSizes(Collection summaries) { if (summaries == null) { return 0; } long total = 0; for (StreamSummary summary : summaries) total += summary.totalSize; return total; } private long getTotalFilesCompleted(Collection files) { Iterable completed = Iterables.filter(files, new Predicate() { public boolean apply(ProgressInfo input) { return input.isCompleted(); } }); return Iterables.size(completed); } }