From 6bf3754e578149d72b06d6e765acd5ddf1c2372b Mon Sep 17 00:00:00 2001 From: codcod Date: Sun, 28 Aug 2022 18:24:34 +0200 Subject: [PATCH 01/16] Dockerize Simulator --- Dockerfile | 21 +++++++++++++++++++++ docker-compose.yaml | 6 ++++++ pom.xml | 10 +++++----- scripts/docker-build | 3 +++ scripts/docker-remove-dangling | 22 ++++++++++++++++++++++ scripts/docker-run | 3 +++ sim/users.txt | 13 ++++++++++--- 7 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yaml create mode 100755 scripts/docker-build create mode 100755 scripts/docker-remove-dangling create mode 100755 scripts/docker-run diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0c55d1a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM maven:3.5-jdk-8-alpine as builder + +COPY . /app/src + +RUN mvn -f /app/src/pom.xml clean package + +FROM ibmjava:8-sdk + +COPY --from=builder /app/src/charset/target/opensmpp-charset-3.0.3-SNAPSHOT.jar /app/charset.jar +COPY --from=builder /app/src/client/target/opensmpp-client-3.0.3-SNAPSHOT.jar /app/client.jar +COPY --from=builder /app/src/core/target/opensmpp-core-3.0.3-SNAPSHOT.jar /app/core.jar +COPY --from=builder /app/src/sim/target/opensmpp-sim-3.0.3-SNAPSHOT.jar /app/sim.jar +COPY sim/users.txt /app/etc/users.txt + +WORKDIR /app + +EXPOSE 2775 + +ENV CLASSPATH=".:charset.jar:client.jar:core.jar:sim.jar" + +ENTRYPOINT ["java", "org.smpp.smscsim.Simulator"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d918ec4 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,6 @@ +version: '3' +services: + simulator: + image: opensmpp-sim:3.0.3 + ports: + - 2775:2775 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9b76dbc..df96889 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,8 @@ http://opensmpp.org/ - 1.5 - 1.5 + 1.8 + 1.8 @@ -200,10 +200,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.0 + 3.8.0 - 1.5 - 1.5 + 1.8 + 1.8 UTF-8 diff --git a/scripts/docker-build b/scripts/docker-build new file mode 100755 index 0000000..7e40386 --- /dev/null +++ b/scripts/docker-build @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker build -t opensmpp-sim:3.0.3 . \ No newline at end of file diff --git a/scripts/docker-remove-dangling b/scripts/docker-remove-dangling new file mode 100755 index 0000000..0fd4242 --- /dev/null +++ b/scripts/docker-remove-dangling @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# remove all: stopped containers, unused networks, dangling images, build cache +# docker system prune + +# remove dangling images + +dangling_images='docker images -f dangling=true -q' + +if [ $( $dangling_images |wc -l ) -gt 0 ]; then + docker rmi $( $dangling_images ) + printf "* Dangling images have been removed\n" +fi + +# remove exited containers + +exited_containers='docker ps -a -f status=exited -f status=created -q' + +if [ $( $exited_containers |wc -l ) -gt 0 ]; then + docker rm $( $exited_containers ) + printf "* Exited containers have been removed\n" +fi diff --git a/scripts/docker-run b/scripts/docker-run new file mode 100755 index 0000000..ce0f8c0 --- /dev/null +++ b/scripts/docker-run @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker run -p 2775:2775 -it opensmpp-sim:3.0.3 \ No newline at end of file diff --git a/sim/users.txt b/sim/users.txt index 7c29b8c..15e37d4 100644 --- a/sim/users.txt +++ b/sim/users.txt @@ -19,9 +19,16 @@ # "peter" and " peter". -# Pavel can bound for unlimited time as any type -name=pavel -password=dfsew +name=smppclient1 +password=password +timeout=unlimited + +name=smppclient2 +password=password +timeout=unlimited + +name=smppclient3 +password=password timeout=unlimited From eb21ed1335ea6bcf28660fe67068fd33a6dfbf74 Mon Sep 17 00:00:00 2001 From: codcod Date: Sun, 28 Aug 2022 20:01:43 +0200 Subject: [PATCH 02/16] Better images that also work on Darwin --- .dockerignore | 1 + Dockerfile | 14 ++++++++++++-- docker-compose.yaml | 4 ++-- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1de5659 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0c55d1a..c2dd098 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,20 @@ -FROM maven:3.5-jdk-8-alpine as builder +# The following images also work but produce images twice as big: +# +# - FROM maven:3-jdk-11-slim AS builder +# - FROM openjdk:11 +# +# The following can be used on MacOS: +# +# FROM --platform=linux/amd64 ibmjava:8-sdk + + +FROM maven:3.6-jdk-8-alpine AS builder COPY . /app/src RUN mvn -f /app/src/pom.xml clean package -FROM ibmjava:8-sdk +FROM adoptopenjdk/openjdk8 COPY --from=builder /app/src/charset/target/opensmpp-charset-3.0.3-SNAPSHOT.jar /app/charset.jar COPY --from=builder /app/src/client/target/opensmpp-client-3.0.3-SNAPSHOT.jar /app/client.jar diff --git a/docker-compose.yaml b/docker-compose.yaml index d918ec4..5f3dd1d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,6 @@ version: '3' services: simulator: - image: opensmpp-sim:3.0.3 + build: . ports: - - 2775:2775 \ No newline at end of file + - 2775:2775 From 9c838c31a29bf7aafd300e3debfd9d3a4d209966 Mon Sep 17 00:00:00 2001 From: codcod Date: Sun, 28 Aug 2022 20:07:12 +0200 Subject: [PATCH 03/16] Add newlines --- .dockerignore | 2 +- Dockerfile | 2 +- scripts/docker-build | 2 +- scripts/docker-run | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.dockerignore b/.dockerignore index 1de5659..eb5a316 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1 @@ -target \ No newline at end of file +target diff --git a/Dockerfile b/Dockerfile index c2dd098..71610ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,4 +28,4 @@ EXPOSE 2775 ENV CLASSPATH=".:charset.jar:client.jar:core.jar:sim.jar" -ENTRYPOINT ["java", "org.smpp.smscsim.Simulator"] \ No newline at end of file +ENTRYPOINT ["java", "org.smpp.smscsim.Simulator"] diff --git a/scripts/docker-build b/scripts/docker-build index 7e40386..d69a91a 100755 --- a/scripts/docker-build +++ b/scripts/docker-build @@ -1,3 +1,3 @@ #!/usr/bin/env bash -docker build -t opensmpp-sim:3.0.3 . \ No newline at end of file +docker build -t opensmpp-sim:3.0.3 . diff --git a/scripts/docker-run b/scripts/docker-run index ce0f8c0..76d06dc 100755 --- a/scripts/docker-run +++ b/scripts/docker-run @@ -1,3 +1,3 @@ #!/usr/bin/env bash -docker run -p 2775:2775 -it opensmpp-sim:3.0.3 \ No newline at end of file +docker run -p 2775:2775 -it opensmpp-sim:3.0.3 From 11e66320dd3d54bce94c493f7b6dde6c7fe85253 Mon Sep 17 00:00:00 2001 From: codcod Date: Sun, 28 Aug 2022 20:13:33 +0200 Subject: [PATCH 04/16] Update Readme re scripts to run Docker --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index dae2c8e..9c9a161 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ bug fixes, and has been generally refactored. * client - a simple SMPP client * sim - a simple SMSC simulator +How to build and run Simulator with Docker: + + $ ./scripts/docker-build + $ ./scripts/docker-run + # Versions Versions of this project are managed according to the From 9cc0e098644849e53c4b431663b314b98385a9f6 Mon Sep 17 00:00:00 2001 From: codcod Date: Sun, 28 Aug 2022 20:29:06 +0200 Subject: [PATCH 05/16] Remove option to choose port and stick with 2775 --- .../main/java/org/smpp/smscsim/Simulator.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sim/src/main/java/org/smpp/smscsim/Simulator.java b/sim/src/main/java/org/smpp/smscsim/Simulator.java index d066542..6a60a77 100644 --- a/sim/src/main/java/org/smpp/smscsim/Simulator.java +++ b/sim/src/main/java/org/smpp/smscsim/Simulator.java @@ -50,7 +50,7 @@ *

* User file can be specified using usersFileName property, e.g.: -DusersFileName=/my/path/to/users.txt *

- * + * * @author Logica Mobile Networks SMPP Open Source Team * @version $Id: Simulator.java 72 2008-07-15 19:43:00Z sverkera $ * @see SimulatorPDUProcessor @@ -197,15 +197,17 @@ protected void menu() throws IOException { /** * Permits a user to choose the port where to listen on and then creates and * starts new instance of SMSCListener. - * An instance of the SimulatorPDUProcessor is created + * An instance of the SimulatorPDUProcessor is created * and this instance is passed to the SMSCListener which is started * just after. */ protected void start() throws IOException { if (smscListener == null) { - System.out.print("Enter port number> "); - int port = Integer.parseInt(keyboard.readLine()); - System.out.print("Starting listener... "); + // System.out.print("Enter port number> "); + // int port = Integer.parseInt(keyboard.readLine()); + // System.out.print("Starting listener... "); + System.out.print("Listening on port 2775 "); + int port = 2775; smscListener = new SMSCListenerImpl(port, true); processors = new PDUProcessorGroup(); messageStore = new ShortMessageStore(); @@ -343,7 +345,7 @@ protected void listClients() { /** * Permits data to be sent to a specific client. - * With the id of the client set by the user, the method sendMessage + * With the id of the client set by the user, the method sendMessage * gets back the specific reference to the client's PDUProcessor. * With this reference you are able to send data to the client. */ @@ -399,7 +401,7 @@ protected void sendMessage() throws IOException { * Revision 1.1 2003/07/23 00:28:39 sverkera * Imported * - * + * * Old changelog: * 20-09-01 ticp@logica.com added support for sending of delivery info * 26-09-01 ticp@logica.com debug now in a group From 0a859cb411c304d5be70e870bf577de5064639c8 Mon Sep 17 00:00:00 2001 From: codcod Date: Thu, 28 Sep 2023 08:54:29 +0200 Subject: [PATCH 06/16] Start Simulator in start mode instead of menu mode --- sim/src/main/java/org/smpp/smscsim/Simulator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sim/src/main/java/org/smpp/smscsim/Simulator.java b/sim/src/main/java/org/smpp/smscsim/Simulator.java index 6a60a77..7c186c5 100644 --- a/sim/src/main/java/org/smpp/smscsim/Simulator.java +++ b/sim/src/main/java/org/smpp/smscsim/Simulator.java @@ -121,7 +121,8 @@ public static void main(String args[]) throws IOException { debug.deactivate(SmppObject.DCOMD); debug.deactivate(DSIMD2); Simulator menu = new Simulator(); - menu.menu(); + //menu.menu(); + menu.start(); } /** From 0c645040a583456033dc5951a279a987b606007f Mon Sep 17 00:00:00 2001 From: codcod Date: Thu, 28 Sep 2023 08:54:52 +0200 Subject: [PATCH 07/16] Add Python client --- client-py/.gitignore | 1 + client-py/README.md | 9 +++++++ client-py/bin/run | 5 ++++ client-py/poetry.lock | 34 +++++++++++++++++++++++ client-py/pyproject.toml | 15 +++++++++++ client-py/smsc_client/__init__.py | 0 client-py/smsc_client/client.py | 45 +++++++++++++++++++++++++++++++ 7 files changed, 109 insertions(+) create mode 100644 client-py/.gitignore create mode 100644 client-py/README.md create mode 100755 client-py/bin/run create mode 100644 client-py/poetry.lock create mode 100644 client-py/pyproject.toml create mode 100644 client-py/smsc_client/__init__.py create mode 100644 client-py/smsc_client/client.py diff --git a/client-py/.gitignore b/client-py/.gitignore new file mode 100644 index 0000000..1d17dae --- /dev/null +++ b/client-py/.gitignore @@ -0,0 +1 @@ +.venv diff --git a/client-py/README.md b/client-py/README.md new file mode 100644 index 0000000..ff9fda5 --- /dev/null +++ b/client-py/README.md @@ -0,0 +1,9 @@ +# Python client for the OpenSMPP Simulator + +Simplistic python client for OpenSMPP Simulator to test the connection mostly. + +Connects to `127.0.0.1` on port 2775 with `smppclient1` as login name and +`password` as password. + + $ poetry install + $ ./bin/run diff --git a/client-py/bin/run b/client-py/bin/run new file mode 100755 index 0000000..2990af3 --- /dev/null +++ b/client-py/bin/run @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +PYTHONPATH=. poetry run python smsc_client/client.py + +# vim: ft=sh:sw=4:et:ai diff --git a/client-py/poetry.lock b/client-py/poetry.lock new file mode 100644 index 0000000..5c8596e --- /dev/null +++ b/client-py/poetry.lock @@ -0,0 +1,34 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "smpplib" +version = "2.2.3" +description = "SMPP library for python" +optional = false +python-versions = "*" +files = [ + {file = "smpplib-2.2.3-py3-none-any.whl", hash = "sha256:62abc429602bd3f4e351ee786eed514f9d12fffc05d1b8d2dc715d96a733820a"}, + {file = "smpplib-2.2.3.tar.gz", hash = "sha256:5215a95b0538d26f189600e0982b31da8281f7453cd6e2862c5b21e3e1002331"}, +] + +[package.dependencies] +six = "*" + +[package.extras] +tests = ["mock", "pytest", "typing"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "ec409d355b3d86c3e35a44577d81486d59f07c796ce7e7eadc088c52633da2be" diff --git a/client-py/pyproject.toml b/client-py/pyproject.toml new file mode 100644 index 0000000..c917500 --- /dev/null +++ b/client-py/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "smsc-client" +version = "0.1.0" +description = "" +authors = ["nicos_backbase "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +smpplib = "^2.2.3" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/client-py/smsc_client/__init__.py b/client-py/smsc_client/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client-py/smsc_client/client.py b/client-py/smsc_client/client.py new file mode 100644 index 0000000..239d8bc --- /dev/null +++ b/client-py/smsc_client/client.py @@ -0,0 +1,45 @@ +import logging +import sys + +import smpplib.gsm +import smpplib.client +import smpplib.consts + +# if you want to know what's happening +logging.basicConfig(level='DEBUG') + +# Two parts, UCS2, SMS with UDH +parts, encoding_flag, msg_type_flag = smpplib.gsm.make_parts(u'Hello world!\n'*10) + +client = smpplib.client.Client('127.0.0.1', 2775, allow_unknown_opt_params=True) + +# Print when obtain message_id +client.set_message_sent_handler( + lambda pdu: sys.stdout.write('sent {} {}\n'.format(pdu.sequence, pdu.message_id))) +client.set_message_received_handler( + lambda pdu: sys.stdout.write('delivered {}\n'.format(pdu.receipted_message_id))) + +client.connect() +client.bind_transceiver(system_id='smppclient1', password='password') + +for part in parts: + pdu = client.send_message( + source_addr_ton=smpplib.consts.SMPP_TON_INTL, + #source_addr_npi=smpplib.consts.SMPP_NPI_ISDN, + # Make sure it is a byte string, not unicode: + source_addr='+48123123123', + + dest_addr_ton=smpplib.consts.SMPP_TON_INTL, + #dest_addr_npi=smpplib.consts.SMPP_NPI_ISDN, + # Make sure thease two params are byte strings, not unicode: + destination_addr='+48321321321', + short_message=part, + + data_coding=encoding_flag, + esm_class=msg_type_flag, + registered_delivery=True, + ) + print(pdu.sequence) + +# Enters a loop, waiting for incoming PDUs +client.listen() From 4bc4c0b5f62dd07119b2bf650d19803e2bed64e8 Mon Sep 17 00:00:00 2001 From: codcod Date: Thu, 28 Sep 2023 08:58:15 +0200 Subject: [PATCH 08/16] Update README --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c9a161..b1799fd 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,23 @@ bug fixes, and has been generally refactored. * client - a simple SMPP client * sim - a simple SMSC simulator -How to build and run Simulator with Docker: +# Simulator + +Build and run Simulator with Docker: $ ./scripts/docker-build $ ./scripts/docker-run +Or use `docker compose`: + + $ docker-compose up -d + +To test Simulator: + + $ cd client-py + $ poetry install + $ ./bin/run + # Versions Versions of this project are managed according to the From 0f88f70de7bf640f713f939bc3714b8828cbca67 Mon Sep 17 00:00:00 2001 From: codcod Date: Thu, 28 Sep 2023 16:08:54 +0200 Subject: [PATCH 09/16] Update README --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b1799fd..1ae99ff 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,23 @@ bug fixes, and has been generally refactored. Build and run Simulator with Docker: - $ ./scripts/docker-build - $ ./scripts/docker-run + $ ./scripts/docker-build + $ ./scripts/docker-run -Or use `docker compose`: +or use `docker compose`: $ docker-compose up -d -To test Simulator: +Send requests to Simulator with Python: $ cd client-py - $ poetry install + $ poetry install # for the first time only $ ./bin/run +in a separate terminal: + + $ docker logs -f opensmpp-simulator-1 + # Versions Versions of this project are managed according to the From a70c2b567b596f8f5cf6274039b2e957a83ca9fc Mon Sep 17 00:00:00 2001 From: codcod Date: Thu, 28 Sep 2023 22:04:11 +0200 Subject: [PATCH 10/16] chore: clean up dockerization of Simulator --- .dockerignore | 2 ++ README.md | 11 +++-------- compose.yaml | 10 ++++++++++ docker-compose.yaml | 6 ------ scripts/docker-build | 3 --- scripts/docker-remove-dangling | 22 ---------------------- scripts/docker-run | 3 --- Dockerfile => sim.Dockerfile | 19 ++++++++++++------- 8 files changed, 27 insertions(+), 49 deletions(-) create mode 100644 compose.yaml delete mode 100644 docker-compose.yaml delete mode 100755 scripts/docker-build delete mode 100755 scripts/docker-remove-dangling delete mode 100755 scripts/docker-run rename Dockerfile => sim.Dockerfile (76%) diff --git a/.dockerignore b/.dockerignore index eb5a316..155a28d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ target +.git +.venv diff --git a/README.md b/README.md index 1ae99ff..b059817 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,17 @@ bug fixes, and has been generally refactored. Build and run Simulator with Docker: - $ ./scripts/docker-build - $ ./scripts/docker-run - -or use `docker compose`: - $ docker-compose up -d -Send requests to Simulator with Python: +send requests to Simulator with Python client: $ cd client-py $ poetry install # for the first time only $ ./bin/run -in a separate terminal: +and in a separate terminal: - $ docker logs -f opensmpp-simulator-1 + $ docker logs -f opensmpp-sim-1 # Versions diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..04a9c84 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,10 @@ +version: "3.8" + +services: + sim: + container_name: opensmpp-sim-1 + image: codcod66/opensmpp-sim + build: + dockerfile: ./sim.Dockerfile + ports: + - "2775:2775" diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index 5f3dd1d..0000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,6 +0,0 @@ -version: '3' -services: - simulator: - build: . - ports: - - 2775:2775 diff --git a/scripts/docker-build b/scripts/docker-build deleted file mode 100755 index d69a91a..0000000 --- a/scripts/docker-build +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -docker build -t opensmpp-sim:3.0.3 . diff --git a/scripts/docker-remove-dangling b/scripts/docker-remove-dangling deleted file mode 100755 index 0fd4242..0000000 --- a/scripts/docker-remove-dangling +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -# remove all: stopped containers, unused networks, dangling images, build cache -# docker system prune - -# remove dangling images - -dangling_images='docker images -f dangling=true -q' - -if [ $( $dangling_images |wc -l ) -gt 0 ]; then - docker rmi $( $dangling_images ) - printf "* Dangling images have been removed\n" -fi - -# remove exited containers - -exited_containers='docker ps -a -f status=exited -f status=created -q' - -if [ $( $exited_containers |wc -l ) -gt 0 ]; then - docker rm $( $exited_containers ) - printf "* Exited containers have been removed\n" -fi diff --git a/scripts/docker-run b/scripts/docker-run deleted file mode 100755 index 76d06dc..0000000 --- a/scripts/docker-run +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -docker run -p 2775:2775 -it opensmpp-sim:3.0.3 diff --git a/Dockerfile b/sim.Dockerfile similarity index 76% rename from Dockerfile rename to sim.Dockerfile index 71610ec..246c0a1 100644 --- a/Dockerfile +++ b/sim.Dockerfile @@ -1,12 +1,8 @@ -# The following images also work but produce images twice as big: -# -# - FROM maven:3-jdk-11-slim AS builder -# - FROM openjdk:11 +# syntax=docker/dockerfile:1 + # -# The following can be used on MacOS: +# build # -# FROM --platform=linux/amd64 ibmjava:8-sdk - FROM maven:3.6-jdk-8-alpine AS builder @@ -14,8 +10,17 @@ COPY . /app/src RUN mvn -f /app/src/pom.xml clean package +# +# compile +# + FROM adoptopenjdk/openjdk8 +LABEL maintainer="codcod" \ + opensmpp-version="3.0.3" \ + opensmpp-dockerized-version="0.0.1" \ + opensmpp-dockerized-date="2023-09-28" + COPY --from=builder /app/src/charset/target/opensmpp-charset-3.0.3-SNAPSHOT.jar /app/charset.jar COPY --from=builder /app/src/client/target/opensmpp-client-3.0.3-SNAPSHOT.jar /app/client.jar COPY --from=builder /app/src/core/target/opensmpp-core-3.0.3-SNAPSHOT.jar /app/core.jar From e4c3670dfb9c86787b63c6f28571443baab0b3dd Mon Sep 17 00:00:00 2001 From: codcod Date: Fri, 20 Oct 2023 21:34:52 +0200 Subject: [PATCH 11/16] chore: occasional maintenance --- README-repository-overview.md | 74 ++++++++++++ README.md | 11 +- client-py/.flake8 | 5 + client-py/.gitignore | 1 + client-py/.tool-versions | 1 + client-py/Makefile | 19 +++ client-py/README.md | 8 +- client-py/bin/run | 5 - client-py/poetry.lock | 207 +++++++++++++++++++++++++++++++- client-py/pyproject.toml | 36 +++++- client-py/smsc_client/client.py | 18 ++- logo.png | Bin 0 -> 22870 bytes sim.Dockerfile | 4 +- 13 files changed, 357 insertions(+), 32 deletions(-) create mode 100644 README-repository-overview.md create mode 100644 client-py/.flake8 create mode 100644 client-py/.tool-versions create mode 100644 client-py/Makefile delete mode 100755 client-py/bin/run create mode 100644 logo.png diff --git a/README-repository-overview.md b/README-repository-overview.md new file mode 100644 index 0000000..90f3a63 --- /dev/null +++ b/README-repository-overview.md @@ -0,0 +1,74 @@ + + +Note: the description for this image can be found at https://github.com/codcod/opensmpp/blob/master/README-repository-overview.md. + +# Quick reference + +- **Maintained by**: + + https://github.com/codcod/opensmpp + +# Supported tags and respective `Dockerfile` links + +- [`0.1.0`, `latest`](https://github.com/codcod/opensmpp/blob/a70c2b567b596f8f5cf6274039b2e957a83ca9fc/sim.Dockerfile) + +# What is OpenSMPP? + +The OpenSmpp API is an open source Java library implementing the SMPP (Short +Message Peer to Peer) protocol. It is based on the original Logica OpenSMPP +API. + +At the moment only SMPP version 3.4 is supported. + +Support for SMPP used to be provided via the forums at smsforum.net (no longer +in existence); but since SMS Forum ceased operations at the end of 2007, +official support is no longer available. + +> http://opensmpp.org + +![logo](http://opensmpp.org/images/opensmpp.png) + +# How to use this image + +## start an opensmpp instance + +```console +$ docker run --rm -p 2775:2775 codcod66/opensmpp-sim +``` + +The default users and passwords are kept [in this file](https://github.com/codcod/opensmpp/blob/a70c2b567b596f8f5cf6274039b2e957a83ca9fc/sim/users.txt). + +## ... or via [`docker compose`](https://github.com/docker/compose) + +Example `compose.yml`: + +```yaml +version: "3.8" + +services: + sim: + container_name: opensmpp-sim-1 + image: codcod66/opensmpp-sim + ports: + - "2775:2775" +``` + +# License + +View [license](https://github.com/codcod/opensmpp/blob/a70c2b567b596f8f5cf6274039b2e957a83ca9fc/LICENSE) +[information](https://github.com/codcod/opensmpp/blob/a70c2b567b596f8f5cf6274039b2e957a83ca9fc/LICENSE_LOGICA) +for the software contained in this image. + +As with all Docker images, these likely also contain other software which may +be under other licenses (such as Bash, etc from the base distribution, along +with any direct or indirect dependencies of the primary software being +contained). + +As for any pre-built image usage, it is the image user's responsibility to +ensure that any use of this image complies with any relevant licenses for all +software contained within. diff --git a/README.md b/README.md index b059817..673c94f 100644 --- a/README.md +++ b/README.md @@ -20,17 +20,10 @@ bug fixes, and has been generally refactored. Build and run Simulator with Docker: $ docker-compose up -d - -send requests to Simulator with Python client: - - $ cd client-py - $ poetry install # for the first time only - $ ./bin/run - -and in a separate terminal: - $ docker logs -f opensmpp-sim-1 +See [client-py](client-py/README.md) for details on how to run the Python client. + # Versions Versions of this project are managed according to the diff --git a/client-py/.flake8 b/client-py/.flake8 new file mode 100644 index 0000000..9846aa4 --- /dev/null +++ b/client-py/.flake8 @@ -0,0 +1,5 @@ +[flake8] +max-line-length = 88 +# required for compatibility with Black: +extend-ignore = E203 +exclude = .* \ No newline at end of file diff --git a/client-py/.gitignore b/client-py/.gitignore index 1d17dae..99971d7 100644 --- a/client-py/.gitignore +++ b/client-py/.gitignore @@ -1 +1,2 @@ .venv +.ruff_cache \ No newline at end of file diff --git a/client-py/.tool-versions b/client-py/.tool-versions new file mode 100644 index 0000000..b4736d5 --- /dev/null +++ b/client-py/.tool-versions @@ -0,0 +1 @@ +python 3.11.6 diff --git a/client-py/Makefile b/client-py/Makefile new file mode 100644 index 0000000..ddbe509 --- /dev/null +++ b/client-py/Makefile @@ -0,0 +1,19 @@ +.PHONY = venv fix run + +APP_DIR=smsc_client + +export PYTHONPATH=. + +venv: + rm -rf ".venv" + poetry install + @printf "\nDone. You can now activate the virtual environment:\n source .venv/bin/activate\n" + +fix: + poetry run black $(APP_DIR) + poetry run flake8 $(APP_DIR) + poetry run isort $(APP_DIR) + poetry run ruff $(APP_DIR)/** + +run: + poetry run python smsc_client/client.py diff --git a/client-py/README.md b/client-py/README.md index ff9fda5..6ede4f3 100644 --- a/client-py/README.md +++ b/client-py/README.md @@ -1,9 +1,11 @@ # Python client for the OpenSMPP Simulator -Simplistic python client for OpenSMPP Simulator to test the connection mostly. +Basic Python client for OpenSMPP Simulator to test the connection mostly. Connects to `127.0.0.1` on port 2775 with `smppclient1` as login name and `password` as password. - $ poetry install - $ ./bin/run + $ make venv + $ make run + +Uses [smpplib](https://github.com/python-smpplib/python-smpplib). diff --git a/client-py/bin/run b/client-py/bin/run deleted file mode 100755 index 2990af3..0000000 --- a/client-py/bin/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh - -PYTHONPATH=. poetry run python smsc_client/client.py - -# vim: ft=sh:sw=4:et:ai diff --git a/client-py/poetry.lock b/client-py/poetry.lock index 5c8596e..ea9f490 100644 --- a/client-py/poetry.lock +++ b/client-py/poetry.lock @@ -1,5 +1,210 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "black" +version = "23.10.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.10.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"}, + {file = "black-23.10.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd"}, + {file = "black-23.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604"}, + {file = "black-23.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8"}, + {file = "black-23.10.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e"}, + {file = "black-23.10.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699"}, + {file = "black-23.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171"}, + {file = "black-23.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c"}, + {file = "black-23.10.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23"}, + {file = "black-23.10.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b"}, + {file = "black-23.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c"}, + {file = "black-23.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9"}, + {file = "black-23.10.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204"}, + {file = "black-23.10.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a"}, + {file = "black-23.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a"}, + {file = "black-23.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747"}, + {file = "black-23.10.0-py3-none-any.whl", hash = "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e"}, + {file = "black-23.10.0.tar.gz", hash = "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "flake8" +version = "6.1.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" + +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pathspec" +version = "0.11.2" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] + +[[package]] +name = "platformdirs" +version = "3.11.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[[package]] +name = "pycodestyle" +version = "2.11.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, +] + +[[package]] +name = "pyflakes" +version = "3.1.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, +] + +[[package]] +name = "ruff" +version = "0.1.1" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.1-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:b7cdc893aef23ccc14c54bd79a8109a82a2c527e11d030b62201d86f6c2b81c5"}, + {file = "ruff-0.1.1-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:620d4b34302538dbd8bbbe8fdb8e8f98d72d29bd47e972e2b59ce6c1e8862257"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a909d3930afdbc2e9fd893b0034479e90e7981791879aab50ce3d9f55205bd6"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3305d1cb4eb8ff6d3e63a48d1659d20aab43b49fe987b3ca4900528342367145"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c34ae501d0ec71acf19ee5d4d889e379863dcc4b796bf8ce2934a9357dc31db7"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6aa7e63c3852cf8fe62698aef31e563e97143a4b801b57f920012d0e07049a8d"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d68367d1379a6b47e61bc9de144a47bcdb1aad7903bbf256e4c3d31f11a87ae"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc11955f6ce3398d2afe81ad7e49d0ebf0a581d8bcb27b8c300281737735e3a3"}, + {file = "ruff-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd8eead88ea83a250499074e2a8e9d80975f0b324b1e2e679e4594da318c25"}, + {file = "ruff-0.1.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f4780e2bb52f3863a565ec3f699319d3493b83ff95ebbb4993e59c62aaf6e75e"}, + {file = "ruff-0.1.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8f5b24daddf35b6c207619301170cae5d2699955829cda77b6ce1e5fc69340df"}, + {file = "ruff-0.1.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d3f9ac658ba29e07b95c80fa742b059a55aefffa8b1e078bc3c08768bdd4b11a"}, + {file = "ruff-0.1.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3521bf910104bf781e6753282282acc145cbe3eff79a1ce6b920404cd756075a"}, + {file = "ruff-0.1.1-py3-none-win32.whl", hash = "sha256:ba3208543ab91d3e4032db2652dcb6c22a25787b85b8dc3aeff084afdc612e5c"}, + {file = "ruff-0.1.1-py3-none-win_amd64.whl", hash = "sha256:3ff3006c97d9dc396b87fb46bb65818e614ad0181f059322df82bbfe6944e264"}, + {file = "ruff-0.1.1-py3-none-win_arm64.whl", hash = "sha256:e140bd717c49164c8feb4f65c644046fe929c46f42493672853e3213d7bdbce2"}, + {file = "ruff-0.1.1.tar.gz", hash = "sha256:c90461ae4abec261609e5ea436de4a4b5f2822921cf04c16d2cc9327182dbbcc"}, +] + [[package]] name = "six" version = "1.16.0" @@ -31,4 +236,4 @@ tests = ["mock", "pytest", "typing"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "ec409d355b3d86c3e35a44577d81486d59f07c796ce7e7eadc088c52633da2be" +content-hash = "0080e8bbbbd4f5448058f46f7763bb1b2537caffda136c75b40b8b40dfd921ca" diff --git a/client-py/pyproject.toml b/client-py/pyproject.toml index c917500..f91b329 100644 --- a/client-py/pyproject.toml +++ b/client-py/pyproject.toml @@ -2,14 +2,48 @@ name = "smsc-client" version = "0.1.0" description = "" -authors = ["nicos_backbase "] +authors = ["codcod"] readme = "README.md" [tool.poetry.dependencies] python = "^3.11" smpplib = "^2.2.3" +[tool.poetry.group.dev.dependencies] +black = "^23.10.0" +flake8 = "^6.1.0" +isort = "^5.12.0" +ruff = "^0.1.1" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 88 +skip-string-normalization = 1 +target-version = ['py310'] + +[tool.isort] +profile = "black" +line_length = 88 +auto_identify_namespace_packages = false +force_single_line = true +known_first_party = ["smsc_client"] + +[tool.ruff] +fixable = ["ALL"] +unfixable = [] + +exclude = [ + ".git", + ".mypy_cache", + ".ruff_cache", + ".venv", + "__pypackages__", + "build", + "dist", +] +line-length = 88 +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" +target-version = "py310" diff --git a/client-py/smsc_client/client.py b/client-py/smsc_client/client.py index 239d8bc..54f370f 100644 --- a/client-py/smsc_client/client.py +++ b/client-py/smsc_client/client.py @@ -1,23 +1,25 @@ import logging import sys -import smpplib.gsm import smpplib.client import smpplib.consts +import smpplib.gsm # if you want to know what's happening logging.basicConfig(level='DEBUG') # Two parts, UCS2, SMS with UDH -parts, encoding_flag, msg_type_flag = smpplib.gsm.make_parts(u'Hello world!\n'*10) +parts, encoding_flag, msg_type_flag = smpplib.gsm.make_parts('Hello world!\n' * 10) client = smpplib.client.Client('127.0.0.1', 2775, allow_unknown_opt_params=True) # Print when obtain message_id client.set_message_sent_handler( - lambda pdu: sys.stdout.write('sent {} {}\n'.format(pdu.sequence, pdu.message_id))) + lambda pdu: sys.stdout.write('sent {} {}\n'.format(pdu.sequence, pdu.message_id)) +) client.set_message_received_handler( - lambda pdu: sys.stdout.write('delivered {}\n'.format(pdu.receipted_message_id))) + lambda pdu: sys.stdout.write('delivered {}\n'.format(pdu.receipted_message_id)) +) client.connect() client.bind_transceiver(system_id='smppclient1', password='password') @@ -25,21 +27,15 @@ for part in parts: pdu = client.send_message( source_addr_ton=smpplib.consts.SMPP_TON_INTL, - #source_addr_npi=smpplib.consts.SMPP_NPI_ISDN, - # Make sure it is a byte string, not unicode: source_addr='+48123123123', - dest_addr_ton=smpplib.consts.SMPP_TON_INTL, - #dest_addr_npi=smpplib.consts.SMPP_NPI_ISDN, - # Make sure thease two params are byte strings, not unicode: destination_addr='+48321321321', short_message=part, - data_coding=encoding_flag, esm_class=msg_type_flag, registered_delivery=True, ) print(pdu.sequence) - + # Enters a loop, waiting for incoming PDUs client.listen() diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..490c2a399a7fe1f378413d5ff1d0b1a53ea88827 GIT binary patch literal 22870 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 literal 0 HcmV?d00001 diff --git a/sim.Dockerfile b/sim.Dockerfile index 246c0a1..b24fb44 100644 --- a/sim.Dockerfile +++ b/sim.Dockerfile @@ -18,8 +18,8 @@ FROM adoptopenjdk/openjdk8 LABEL maintainer="codcod" \ opensmpp-version="3.0.3" \ - opensmpp-dockerized-version="0.0.1" \ - opensmpp-dockerized-date="2023-09-28" + opensmpp-dockerized-version="0.1.0" \ + opensmpp-dockerized-date="2023-10-20" COPY --from=builder /app/src/charset/target/opensmpp-charset-3.0.3-SNAPSHOT.jar /app/charset.jar COPY --from=builder /app/src/client/target/opensmpp-client-3.0.3-SNAPSHOT.jar /app/client.jar From 3edf3b213e075fd62804aabbc900f38d952e1816 Mon Sep 17 00:00:00 2001 From: codcod Date: Wed, 1 Nov 2023 17:28:19 +0100 Subject: [PATCH 12/16] chore: add examples --- client-py/.gitignore | 4 +- client-py/Makefile | 2 +- client-py/poetry.lock | 19 ++- client-py/pyproject.toml | 12 +- client-py/smsc_client/{client.py => app1.py} | 0 client-py/smsc_client/app2.py | 119 +++++++++++++++++++ client-py/smsc_client/settings.py | 57 +++++++++ 7 files changed, 209 insertions(+), 4 deletions(-) rename client-py/smsc_client/{client.py => app1.py} (100%) create mode 100644 client-py/smsc_client/app2.py create mode 100644 client-py/smsc_client/settings.py diff --git a/client-py/.gitignore b/client-py/.gitignore index 99971d7..0ecec24 100644 --- a/client-py/.gitignore +++ b/client-py/.gitignore @@ -1,2 +1,4 @@ .venv -.ruff_cache \ No newline at end of file +.ruff_cache +__pycache__ +*.log \ No newline at end of file diff --git a/client-py/Makefile b/client-py/Makefile index ddbe509..ffced4c 100644 --- a/client-py/Makefile +++ b/client-py/Makefile @@ -16,4 +16,4 @@ fix: poetry run ruff $(APP_DIR)/** run: - poetry run python smsc_client/client.py + poetry run python smsc_client/app2.py diff --git a/client-py/poetry.lock b/client-py/poetry.lock index ea9f490..7d51353 100644 --- a/client-py/poetry.lock +++ b/client-py/poetry.lock @@ -65,6 +65,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "colorlog" +version = "6.7.0" +description = "Add colours to the output of Python's logging module." +optional = false +python-versions = ">=3.6" +files = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +development = ["black", "flake8", "mypy", "pytest", "types-colorama"] + [[package]] name = "flake8" version = "6.1.0" @@ -236,4 +253,4 @@ tests = ["mock", "pytest", "typing"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "0080e8bbbbd4f5448058f46f7763bb1b2537caffda136c75b40b8b40dfd921ca" +content-hash = "6417f769328dd090521b89acca1aa1dee22764a608c1912794d0796524e60c33" diff --git a/client-py/pyproject.toml b/client-py/pyproject.toml index f91b329..87b0d5a 100644 --- a/client-py/pyproject.toml +++ b/client-py/pyproject.toml @@ -8,6 +8,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.11" smpplib = "^2.2.3" +colorlog = "^6.7.0" [tool.poetry.group.dev.dependencies] black = "^23.10.0" @@ -22,7 +23,16 @@ build-backend = "poetry.core.masonry.api" [tool.black] line-length = 88 skip-string-normalization = 1 -target-version = ['py310'] +target-version = ["py310"] +include = '\.pyi?$' +extend-exclude = ''' +# A regex preceded with ^/ will apply only to files and directories +# in the root of the project. +( + ^/foo.py # exclude a file named foo.py in the root of the project + | settings.py # exclude settings file anywhere in the project +) +''' [tool.isort] profile = "black" diff --git a/client-py/smsc_client/client.py b/client-py/smsc_client/app1.py similarity index 100% rename from client-py/smsc_client/client.py rename to client-py/smsc_client/app1.py diff --git a/client-py/smsc_client/app2.py b/client-py/smsc_client/app2.py new file mode 100644 index 0000000..358455a --- /dev/null +++ b/client-py/smsc_client/app2.py @@ -0,0 +1,119 @@ +import logging.config +from functools import partial +from functools import singledispatch +from threading import Thread + +from smpplib import command +from smpplib import consts +from smpplib import gsm +from smpplib.client import Client +from smpplib.pdu import PDU + +from smsc_client import settings + +logging.config.dictConfig(settings.LOGGING) +logger = logging.getLogger('SMSCApp2') + +SMSC_HOST = settings.SMSC_HOST +SMSC_PORT = settings.SMSC_PORT + + +def extract_message_id(short_message: bytes) -> str: + """Extract internal SMSC message id from `short_message` attribute. + + The reason is `deliver_sm` PDU has an empty `receipted_message_id` + attribute. + + The following is an example of `short_message` attribute from `deliver_sm` + PDU sent by SMSC: + + b'id:Smsc2108 \ + sub:1 \ + dlvrd:1 \ + submit \ + date:2311011357 \ + done \ + date:2311011357 \ + stat:DELIVRD \ + err:0 \ + text:Hi everyone' + """ + step1 = short_message.decode() + step2 = step1.split()[0] + step3 = step2.split(':')[1] + return step3 + + +@singledispatch +def handle_pdu(pdu: PDU): + raise AttributeError(f'Unsupported type {type(pdu)}') + + +@handle_pdu.register +def handle_deliver_sm(pdu: command.DeliverSM): + logger.info( + f'[SMSC] message id={extract_message_id(pdu.short_message)} was delivered' + ) + + +@handle_pdu.register +def handle_submit_sm_resp(pdu: command.SubmitSMResp): + logger.info(f'[SMSC] message was submitted, id={pdu.message_id.decode()}') + + +def send_message(client: Client, sender: str, recipient: str, message: str): + parts, encoding_flag, msg_type_flag = gsm.make_parts(message) + for part in parts: + pdu = client.send_message( + source_addr=sender, + destination_addr=recipient, + short_message=part, + data_coding=encoding_flag, + esm_class=msg_type_flag, + source_addr_ton=consts.SMPP_TON_INTL, + dest_addr_ton=consts.SMPP_TON_INTL, + registered_delivery=True, + ) + logger.debug( + f'Message sent\n' + f'> PDU {pdu.client=}\n' + f'> PDU {pdu.command=}\n' + f'> PDU {pdu.destination_addr=}\n' + f'> PDU {pdu.length=}\n' + f'> PDU {pdu.sequence=}\n' + f'> PDU {pdu.short_message=}\n' + f'> PDU {pdu.sm_length=}\n' + f'> PDU {pdu.source_addr=}' + ) + + +client = Client( + SMSC_HOST, + SMSC_PORT, + allow_unknown_opt_params=True, + logger_name='smpp.Client', + timeout=10, +) +client.set_message_received_handler(lambda pdu: handle_pdu(pdu)) +client.set_message_sent_handler(lambda pdu: handle_pdu(pdu)) + +client.connect() +client.bind_transceiver(system_id='smppclient1', password='password') + +send = partial(send_message, client) + +# try: +# client.listen() # enters into a loop +# except KeyboardInterrupt: +# logger.error('Interrupted, exiting...') +# finally: +# client.unbind() +# client.disconnect() + +t = Thread(target=client.listen) +t.start() + +if __name__ == '__main__': + send(sender='123', recipient='321', message='Hi 1000') + send(sender='123', recipient='321', message='Hi 2000') + send(sender='123', recipient='321', message='Hi 3000') diff --git a/client-py/smsc_client/settings.py b/client-py/smsc_client/settings.py new file mode 100644 index 0000000..4fb817f --- /dev/null +++ b/client-py/smsc_client/settings.py @@ -0,0 +1,57 @@ +""" App settings. +""" + +SMSC_HOST = '127.0.01' + +SMSC_PORT = 2775 + +LOGGING = { + 'version': 1, + 'formatters': { + 'detailed': { + 'class': 'logging.Formatter', + 'format': '%(asctime)s %(name)s %(levelname)-6s %(message)s', + }, + 'colored': { + '()': 'colorlog.ColoredFormatter', + 'format': '%(asctime)s %(log_color)s[%(levelname)-7s]%(reset)s' + ' %(name)-12s %(message_log_color)s%(message)s', + 'datefmt': '%H:%M:%S', + 'secondary_log_colors': { + 'message': { + 'DEBUG': 'light_cyan', + 'INFO': 'green', + 'WARNING': 'yellow', + 'ERROR': 'red', + 'CRITICAL': 'bold_red', + }, + }, + }, + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'level': 'DEBUG', + 'formatter': 'colored', + }, + 'file': { + 'class': 'logging.FileHandler', + 'filename': './smsc_client.log', + 'mode': 'a', + 'level': 'INFO', + 'formatter': 'detailed', + }, + }, + 'loggers': { + 'root': { + 'level': 'DEBUG', + 'handlers': ['console', 'file'], + 'propagate': False + }, + 'smpp.Client': { + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False + }, + }, +} From fe5dc345b3fff3134c3174fe4d6d3f14c89f1f68 Mon Sep 17 00:00:00 2001 From: codcod Date: Wed, 1 Nov 2023 17:35:13 +0100 Subject: [PATCH 13/16] typo --- client-py/smsc_client/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-py/smsc_client/settings.py b/client-py/smsc_client/settings.py index 4fb817f..ec1e069 100644 --- a/client-py/smsc_client/settings.py +++ b/client-py/smsc_client/settings.py @@ -1,7 +1,7 @@ """ App settings. """ -SMSC_HOST = '127.0.01' +SMSC_HOST = '127.0.0.1' SMSC_PORT = 2775 From ee6e14569c8ddd1c614990dda6e8d0c693fbb35b Mon Sep 17 00:00:00 2001 From: Nikos Date: Wed, 1 Nov 2023 17:41:46 +0100 Subject: [PATCH 14/16] Update README.md add link to Docker Hub --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 673c94f..45c3595 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Build and run Simulator with Docker: $ docker-compose up -d $ docker logs -f opensmpp-sim-1 +Get the image from [Docker Hub](https://hub.docker.com/r/codcod66/opensmpp-sim). + See [client-py](client-py/README.md) for details on how to run the Python client. # Versions From 5524550be8ec185922d25963219189133ee15974 Mon Sep 17 00:00:00 2001 From: Nikos Date: Wed, 1 Nov 2023 17:42:21 +0100 Subject: [PATCH 15/16] Rename README-repository-overview.md to README-docker-hub-repository-overview.md more informative file name --- ...sitory-overview.md => README-docker-hub-repository-overview.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README-repository-overview.md => README-docker-hub-repository-overview.md (100%) diff --git a/README-repository-overview.md b/README-docker-hub-repository-overview.md similarity index 100% rename from README-repository-overview.md rename to README-docker-hub-repository-overview.md From 3a2ed90a568773390700b551a044d0f702188d0f Mon Sep 17 00:00:00 2001 From: codcod Date: Wed, 1 Nov 2023 17:56:02 +0100 Subject: [PATCH 16/16] docs: update --- client-py/README.md | 10 ++++++++++ client-py/smsc_client/app2.py | 2 ++ 2 files changed, 12 insertions(+) diff --git a/client-py/README.md b/client-py/README.md index 6ede4f3..bdf881d 100644 --- a/client-py/README.md +++ b/client-py/README.md @@ -8,4 +8,14 @@ Connects to `127.0.0.1` on port 2775 with `smppclient1` as login name and $ make venv $ make run +Or interactively: + + $ make venv + $ poetry shell + $ python + Python 3.12.0 (main, Oct 2 2023, 12:03:24) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin + >>> from smsc_client import app2 + >>> app2.send(sender='123', recipient='321', message='Hi 1000') + >>> ^D ^C + Uses [smpplib](https://github.com/python-smpplib/python-smpplib). diff --git a/client-py/smsc_client/app2.py b/client-py/smsc_client/app2.py index 358455a..900ec3c 100644 --- a/client-py/smsc_client/app2.py +++ b/client-py/smsc_client/app2.py @@ -11,6 +11,8 @@ from smsc_client import settings +__all__ = 'send' + logging.config.dictConfig(settings.LOGGING) logger = logging.getLogger('SMSCApp2')