Skip to content

Commit 80fa54d

Browse files
committed
Add Lab 10 assignment
1 parent 3062f72 commit 80fa54d

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

11-network-ii/lab/README.md

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
# Music Streaming Platform 🎵🎧
2+
3+
## Мрежово програмиране
4+
5+
Тази задача има за цел да ви запознае с разработката на клиент-сървър приложения чрез създаване на опростена платформа за стрийминг на музика.
6+
Музиката е универсален език, който свързва хора от различни култури и поколения. С развитието на интернет и мобилните устройства, приложенията за streaming музика като Spotify и Apple Music се превърнаха в неразделна част от ежедневието ни.
7+
8+
В рамките на задачата ще разработите **клиент-сървър приложение**, при което:
9+
- Сървърът съхранява и управлява плейлисти и песни;
10+
- Клиентите комуникират със сървъра чрез текстови команди.
11+
12+
## Music Streaming Platform Client
13+
14+
Всеки клиент:
15+
- може да създава плейлисти
16+
- може да добавя песни към плейлисти
17+
- може да търси плейлисти по име
18+
- може да преглежда песните в дадена плейлиста
19+
- може да харесва и "отхаресва" песни
20+
- може да прекрати връзката със сървъра по всяко време.
21+
22+
## Music Streaming Platform Server
23+
24+
Сървърът:
25+
- трябва да обслужва множество клиенти едновременно
26+
- получава команди от клиентите и връща резултат
27+
- управлява плейлисти, песни и броя на харесванията.
28+
29+
Имплементирайте следния конструктор:
30+
31+
```java
32+
public MusicStreamingServer(int port, PlaylistRepository playlistRepository)
33+
```
34+
35+
Както и следните методи:
36+
37+
```java
38+
public void start() - стартира сървъра на зададения в конструктора порт
39+
public void stop() - спира сървъра и зачиства ресурсите
40+
```
41+
42+
## Команди
43+
44+
### create-playlist
45+
46+
```
47+
create-playlist <playlist_name>
48+
```
49+
50+
Създава нова плейлиста.
51+
52+
Ограничения:
53+
- името е една дума (без интервали);
54+
- не може да съществуват две плейлисти с едно и също име.
55+
56+
### add-song
57+
58+
```
59+
add-song <playlist_name> <song_title> <artist_name> <duration>
60+
```
61+
62+
Добавя песен към плейлиста.
63+
64+
Ограничения:
65+
- `song_title` и `artist_name` са една дума;
66+
- `duration` е цяло число (секунди);
67+
- една и съща песен (заглавие + артист) не може да бъде добавяна два пъти.
68+
69+
### like-song
70+
71+
```
72+
like-song <playlist_name> <song_title> <artist_name>
73+
```
74+
75+
Увеличава броя харесвания с 1.
76+
77+
### unlike-song
78+
79+
```
80+
unlike-song <playlist_name> <song_title> <artist_name>
81+
```
82+
83+
Намалява броя харесвания с 1 (минимум 0).
84+
85+
### list-playlists
86+
87+
```
88+
list-playlists
89+
```
90+
91+
Връща списък с всички плейлисти.
92+
93+
### get-playlist
94+
95+
```
96+
get-playlist <playlist_name>
97+
```
98+
99+
Връща детайлна информация за плейлиста.
100+
101+
### disconnect
102+
103+
```
104+
disconnect
105+
```
106+
107+
Прекратява връзката със сървъра.
108+
109+
## Примерна сесия
110+
111+
```bash
112+
create-playlist MyFavorites
113+
{"status":"OK","message":"Playlist MyFavorites created successfully."}
114+
115+
add-song MyFavorites Imagine John-Lennon 183
116+
{"status":"OK","message":"Song Imagine by John-Lennon added successfully."}
117+
118+
like-song MyFavorites Imagine John-Lennon
119+
{"status":"OK","message":"Song Imagine by John-Lennon liked. Likes: 1"}
120+
121+
get-playlist MyFavorites
122+
{"status":"OK","playlist":{"name":"MyFavorites","songs":[{"title":"Imagine","artist":"John-Lennon","duration":183,"likes":1}]}}
123+
```
124+
125+
## Интерфейси
126+
127+
Имплементирайте следния интерфейс като създадете клас `InMemoryPlaylistRepository` с конструктор по подразбиране:
128+
129+
```java
130+
package bg.sofia.uni.fmi.mjt.music.server.repository;
131+
132+
import bg.sofia.uni.fmi.mjt.music.server.model.Playlist;
133+
134+
import java.util.Collection;
135+
136+
public interface PlaylistRepository {
137+
138+
/**
139+
* Creates a new playlist with the given name.
140+
*
141+
* @param playlistName the name of the playlist to be created.
142+
* The name must be a single word (no whitespaces).
143+
* @throws PlaylistAlreadyExistsException if a playlist with the given name
144+
* already exists.
145+
*/
146+
void createPlaylist(String playlistName) throws PlaylistAlreadyExistsException;
147+
148+
/**
149+
* Adds a new song to an existing playlist.
150+
*
151+
* @param playlistName the name of the playlist to which the song will be added.
152+
* @param songTitle the title of the song.
153+
* @param artistName the name of the artist.
154+
* @param duration the duration of the song in seconds.
155+
* @throws PlaylistNotFoundException if the playlist with the given name
156+
* does not exist.
157+
* @throws SongAlreadyExistsException if a song with the same title and artist
158+
* already exists in the playlist.
159+
*/
160+
void addSong(String playlistName, String songTitle, String artistName, int duration)
161+
throws PlaylistNotFoundException, SongAlreadyExistsException;
162+
163+
/**
164+
* Increases the number of likes of a given song in the playlist by 1.
165+
*
166+
* @param playlistName the name of the playlist.
167+
* @param songTitle the title of the song.
168+
* @param artistName the name of the artist.
169+
* @return the updated number of likes for the song.
170+
* @throws PlaylistNotFoundException if the playlist does not exist.
171+
* @throws SongNotFoundException if the song does not exist in the playlist.
172+
*/
173+
int likeSong(String playlistName, String songTitle, String artistName)
174+
throws PlaylistNotFoundException, SongNotFoundException;
175+
176+
/**
177+
* Decreases the number of likes of a given song in the playlist by 1.
178+
* The number of likes cannot be less than 0.
179+
*
180+
* @param playlistName the name of the playlist.
181+
* @param songTitle the title of the song.
182+
* @param artistName the name of the artist.
183+
* @return the updated number of likes for the song.
184+
* @throws PlaylistNotFoundException if the playlist does not exist.
185+
* @throws SongNotFoundException if the song does not exist in the playlist.
186+
*/
187+
int unlikeSong(String playlistName, String songTitle, String artistName)
188+
throws PlaylistNotFoundException, SongNotFoundException;
189+
190+
/**
191+
* Retrieves the names of all existing playlists.
192+
*
193+
* @return a collection containing the names of all playlists.
194+
* If no playlists exist, an empty collection is returned.
195+
*/
196+
Collection<String> getAllPlaylists();
197+
198+
/**
199+
* Retrieves detailed information about a playlist with the given name.
200+
*
201+
* @param playlistName the name of the playlist to retrieve.
202+
* @return the {@link Playlist} object containing information about the playlist
203+
* and all of its songs.
204+
* @throws PlaylistNotFoundException if the playlist does not exist.
205+
*/
206+
Playlist getPlaylist(String playlistName) throws PlaylistNotFoundException;
207+
208+
}
209+
```
210+
211+
## Модели
212+
213+
```java
214+
public record Playlist(String name, Set<Song> songs) {}
215+
public record Song(String title, String artist, int duration, int likes) {}
216+
```
217+
218+
- Две песни са еднакви, ако заглавието и артистът съвпадат.
219+
220+
## Валидации
221+
222+
Уверете се, че всички команди са валидирани и връщат съобщение за грешка, ако форматът на командата не е валиден.
223+
224+
Пример:
225+
226+
```
227+
add-song MyFavorites
228+
```
229+
230+
Отговор:
231+
232+
```json
233+
{"status":"ERROR","message":"Usage: add-song <playlist_name> <song_title> <artist_name> <duration>"}
234+
```
235+
236+
## Тестване
237+
238+
⭐ Тествайте ръчно имплементацията, първо с един, а после с няколко паралелно свързани клиента, и се убедете, че работи коректно.
239+
240+
⭐ Писането на автоматични тестове за тази задача е по ваш избор, но съветваме всеки да пробва, тъй като ще ви е полезно и за курсовите проекти.
241+
242+
👉 Подсказка: Припомнете си различните имплементации на Echo Client-Server. Можем ли да ги превърнем в Music Streaming Platform 🎵🎧 Client-Server приложение?
243+
244+
👉 Подсказка: Решението на тази задача ще ви улесни изключително много при разработката на курсовите ви проекти, защото всички те представляват приложения тип клиент-сървър, като сървърът обслужва много потребители едновременно.
245+
246+
## Примерна структура на проекта
247+
248+
Добра практика при създаването на приложения тип клиент-сървър е да отделяте клиента и сървъра в отделни проекти. Това предотвратява грешки от типа, класове/интерфейси от клиента да се ползват от сървъра, или обратно. Също така, в реална ситуация, бихме искали да пакетираме и разпространяваме поотделно клиентската и сървърната част на нашето приложение. Като минимум, отделете имплементацията на клиента и сървъра в отделни пакети.
249+
250+
В грейдъра качете папки `src` и `test`, ако имате тестове (или техен общ `zip` архив).
251+
252+
```
253+
src
254+
└─ bg.sofia.uni.fmi.mjt.music
255+
├── client
256+
│ └── MusicStreamingClient.java
257+
├── server
258+
│ ├── MusicStreamingServer.java
259+
│ ├── model
260+
│ │ ├── Playlist.java
261+
│ │ ├── Song.java
262+
│ │ └── (...)
263+
│ ├── repository
264+
│ │ ├── InMemoryPlaylistRepository.java
265+
│ │ ├── PlaylistRepository.java
266+
│ │ ├── exception
267+
│ │ │ ├── PlaylistAlreadyExistsException.java
268+
│ │ │ ├── PlaylistNotFoundException.java
269+
│ │ │ ├── SongAlreadyExistsException.java
270+
│ │ │ └── SongNotFoundException.java
271+
│ │ └── (...)
272+
│ └── (...)
273+
└── (...)
274+
```
275+
276+
В грейдъра качете папките `src` и `test`, ако имате тестове (или техен общ архив).

0 commit comments

Comments
 (0)