I have an Axon Command which has an moneta Money object.
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.javamoney.moneta.Money;
import java.time.LocalDate;
import java.util.UUID;
#Getter
#SuperBuilder
#ToString
public class MyAxonCommand {
private final UUID id;
private final Money hoogte;
private final LocalDate opleggingsdatum;
}
When i send this command with axon there is an exception.
commandGateway.sendAndWait(myAxonCommand.builder()
.id(new UUID(1, 1))
.hoogte(Money.of(0, "EUR"))
.opleggingsdatum(LocalDate.now())
.build());
The exception thrown is Caused by:
18:07:37.456 [main] INFO org.javamoney.moneta.DefaultMonetaryContextFactory - Using custom MathContext: precision=256, roundingMode=HALF_EVEN
18:07:37.465 [main] INFO nl.ind.handhaving.adapter.messaging.incoming.IndigoListener kvk:987654321 zn:Z1-31190106952 - INDiGO bericht ontvangen op methode: receiveMaatregelOpgelegd
18:07:37.928 [docker-java-stream--1691755530] INFO docker.axonserver - STDOUT: 2023-01-18 17:07:37.925 WARN 1 --- [nio-8024-exec-3] A.i.a.a.rest.DevelopmentRestController : [<anonymous>] Request to delete all events in context "default".
18:07:37.941 [EventProcessor[nl.ind.handhaving.application.query]-0] WARN org.axonframework.eventhandling.TrackingEventProcessor - Error occurred. Starting retry mode.
org.axonframework.axonserver.connector.AxonServerException: The Event Stream has been closed, so no further events can be retrieved
at org.axonframework.axonserver.connector.event.axon.EventBuffer.peekNullable(EventBuffer.java:178)
at org.axonframework.axonserver.connector.event.axon.EventBuffer.hasNextAvailable(EventBuffer.java:144)
at org.axonframework.eventhandling.TrackingEventProcessor.processBatch(TrackingEventProcessor.java:401)
at org.axonframework.eventhandling.TrackingEventProcessor.processingLoop(TrackingEventProcessor.java:300)
at org.axonframework.eventhandling.TrackingEventProcessor$TrackingSegmentWorker.run(TrackingEventProcessor.java:1072)
at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.cleanUp(TrackingEventProcessor.java:1263)
at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.run(TrackingEventProcessor.java:1240)
at java.base/java.lang.Thread.run(Thread.java:833)
18:07:37.942 [EventProcessor[nl.ind.handhaving.application.query]-0] WARN org.axonframework.eventhandling.TrackingEventProcessor - Releasing claim on token and preparing for retry in 1s
18:07:37.945 [EventProcessor[nl.ind.handhaving.application]-0] WARN org.axonframework.eventhandling.TrackingEventProcessor - Error occurred. Starting retry mode.
org.axonframework.axonserver.connector.AxonServerException: The Event Stream has been closed, so no further events can be retrieved
at org.axonframework.axonserver.connector.event.axon.EventBuffer.peekNullable(EventBuffer.java:178)
at org.axonframework.axonserver.connector.event.axon.EventBuffer.hasNextAvailable(EventBuffer.java:144)
at org.axonframework.eventhandling.TrackingEventProcessor.processBatch(TrackingEventProcessor.java:401)
at org.axonframework.eventhandling.TrackingEventProcessor.processingLoop(TrackingEventProcessor.java:300)
at org.axonframework.eventhandling.TrackingEventProcessor$TrackingSegmentWorker.run(TrackingEventProcessor.java:1072)
at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.cleanUp(TrackingEventProcessor.java:1263)
at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.run(TrackingEventProcessor.java:1240)
at java.base/java.lang.Thread.run(Thread.java:833)
18:07:37.945 [EventProcessor[nl.ind.handhaving.application]-0] WARN org.axonframework.eventhandling.TrackingEventProcessor - Releasing claim on token and preparing for retry in 1s
18:07:37.947 [EventProcessor[nl.ind.handhaving.application]-0] INFO org.axonframework.eventhandling.TrackingEventProcessor - Released claim
18:07:37.949 [EventProcessor[nl.ind.handhaving.application.query]-0] INFO org.axonframework.eventhandling.TrackingEventProcessor - Released claim
org.axonframework.commandhandling.CommandExecutionException: org.javamoney.moneta.spi.JDKCurrencyAdapter
at org.axonframework.axonserver.connector.ErrorCode.lambda$static$11(ErrorCode.java:88)
at org.axonframework.axonserver.connector.ErrorCode.convert(ErrorCode.java:182)
at org.axonframework.axonserver.connector.command.CommandSerializer.deserialize(CommandSerializer.java:164)
at org.axonframework.axonserver.connector.command.AxonServerCommandBus.lambda$doDispatch$1(AxonServerCommandBus.java:161)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
at io.axoniq.axonserver.connector.command.impl.CommandChannelImpl$CommandResponseHandler.onNext(CommandChannelImpl.java:372)
at io.axoniq.axonserver.connector.command.impl.CommandChannelImpl$CommandResponseHandler.onNext(CommandChannelImpl.java:359)
at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onMessage(ClientCalls.java:466)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:661)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:646)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: AxonServerRemoteCommandHandlingException{message=An exception was thrown by the remote message handling component: org.javamoney.moneta.spi.JDKCurrencyAdapter, errorCode='AXONIQ-4002', server='134589#xxxxxxxxx}
at org.axonframework.axonserver.connector.ErrorCode.lambda$static$11(ErrorCode.java:86)
... 16 more}
The Axonserver logging - running in a docker :
2023-01-18T17:30:30.237808536Z _ ____
2023-01-18T17:30:30.237852159Z / \ __ _____ _ __ / ___| ___ _ ____ _____ _ __
2023-01-18T17:30:30.237857221Z / _ \ \ \/ / _ \| '_ \\___ \ / _ \ '__\ \ / / _ \ '__|
2023-01-18T17:30:30.237861155Z / ___ \ > < (_) | | | |___) | __/ | \ V / __/ |
2023-01-18T17:30:30.237864060Z /_/ \_\/_/\_\___/|_| |_|____/ \___|_| \_/ \___|_|
2023-01-18T17:30:30.237866979Z Standard Edition Powered by AxonIQ
2023-01-18T17:30:30.237869529Z
2023-01-18T17:30:30.237872060Z version: 4.5.16
2023-01-18T17:30:30.326181167Z 2023-01-18 17:30:30.321 INFO 1 --- [ main] io.axoniq.axonserver.AxonServer : Starting AxonServer using Java 11.0.14 on c32eb57825c4 with PID 1 (/app/classes started by root in /)
2023-01-18T17:30:30.331544104Z 2023-01-18 17:30:30.325 INFO 1 --- [ main] io.axoniq.axonserver.AxonServer : No active profile set, falling back to 1 default profile: "default"
2023-01-18T17:30:33.989108312Z 2023-01-18 17:30:33.988 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8024 (http)
2023-01-18T17:30:34.235755158Z 2023-01-18 17:30:34.231 INFO 1 --- [ main] A.i.a.a.c.MessagingPlatformConfiguration : Configuration initialized with SSL DISABLED and access control DISABLED.
2023-01-18T17:30:37.126812182Z 2023-01-18 17:30:37.125 INFO 1 --- [ main] io.axoniq.axonserver.AxonServer : Axon Server version 4.5.16
2023-01-18T17:30:39.285810090Z 2023-01-18 17:30:39.285 WARN 1 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
2023-01-18T17:30:39.285860293Z
2023-01-18T17:30:39.285865737Z Using generated security password: f23552a4-9623-4adb-831e-506eac6a10a9
2023-01-18T17:30:39.285868706Z
2023-01-18T17:30:39.285871675Z This generated password is for development use only. Your security configuration must be updated before running your application in production.
2023-01-18T17:30:39.285874618Z
2023-01-18T17:30:41.633817404Z 2023-01-18 17:30:41.633 INFO 1 --- [ main] io.axoniq.axonserver.grpc.Gateway : Axon Server Gateway started on port: 8124 - no SSL
2023-01-18T17:30:41.667366113Z 2023-01-18 17:30:41.667 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8024 (http) with context path ''
2023-01-18T17:30:42.561266508Z 2023-01-18 17:30:42.555 INFO 1 --- [ main] io.axoniq.axonserver.AxonServer : Started AxonServer in 12.861 seconds (JVM running for 13.412)
2023-01-18T17:30:57.342935513Z 2023-01-18 17:30:57.338 INFO 1 --- [grpc-executor-1] i.a.a.logging.TopologyEventsLogger : Application connected: handhaving-service, clientId = 149931#v2l1-xxxxl, clientStreamId = 149931#v2l1-xxxxx.87e0f589-66d8-41ee-ab4a-7bc599cc2c01, context = default
2023-01-18T17:31:02.213813565Z 2023-01-18 17:31:02.213 WARN 1 --- [nio-8024-exec-3] A.i.a.a.rest.DevelopmentRestController : [<anonymous>] Request to delete all events in context "default".
2023-01-18T17:31:04.567541554Z 2023-01-18 17:31:04.567 INFO 1 --- [grpc-executor-3] i.a.a.logging.TopologyEventsLogger : Application disconnected: handhaving-service, clientId = 149931#xxxxx.87e0f589-66d8-41ee-ab4a-7bc599cc2c01, context = default: Platform connection completed by client
The issue seems to be that Axon is storing this Money object in a database, according the errorCode='AXONIQ-4002'.
What can i do to fix this? Does Axon needs a hibernate UserType so Axon is able to store this Money object or some other kind of type converter?
It seems that the de-serilizer in the axon server has problems with the Money object.
In order to store this Money object in a view database - where i store the event generated by the command - i had to make a type conversion for hibernate. this seems to be related to the occurred exception.
The project uses:
Spring Boot 2.7.6
axon-spring-boot-starter 4.5.15
moneta 1.4.2
It al runs with Java Temurin 17.0.4
For axon we have no configuration for serializing so the default is used: XML
I have installed Airflow 2.2.5 in my local VM (Oracle Virtual Box 8.6) with MySQL 8.0 as database backend and went through the installation process shown in the website (https://airflow.apache.org/docs/apache-airflow/stable/installation/index.html).
I am using the 'sql_alchemy_conn' argument below:
mysql+mysqlconnector://airflow_user:airflow_password#localhost:3306/airflow_db
I managed to install Airflow, its dependencies (at least what has been asked throughout the process) and got to a point where I can log in to the webserver. However the webserver says the scheduler is not running, as show in the picture:
When I execute "airflow scheduler" in the terminal, I get the following error:
[2022-09-14 15:43:28,943] {authentication.py:59} INFO - package: mysql.connector.plugins
[2022-09-14 15:43:28,947] {authentication.py:60} INFO - plugin_name: mysql_native_password
[2022-09-14 15:43:28,953] {authentication.py:64} INFO - AUTHENTICATION_PLUGIN_CLASS: MySQLNativePasswordAuthPlugin
____________ _____________
____ |__( )_________ __/__ /________ __
____ /| |_ /__ ___/_ /_ __ /_ __ \_ | /| / /
___ ___ | / _ / _ __/ _ / / /_/ /_ |/ |/ /
_/_/ |_/_/ /_/ /_/ /_/ \____/____/|__/
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 398, in _process_params_dict
conv = to_mysql(conv)
File "/usr/local/lib/python3.6/site-packages/mysql/connector/conversion.py", line 194, in to_mysql
) from None
TypeError: Python 'taskinstancestate' cannot be converted to a MySQL type
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1277, in _execute_context
cursor, statement, parameters, context
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/default.py", line 608, in do_execute
cursor.execute(statement, parameters)
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 541, in execute
stmt = _bytestr_format_dict(stmt, self._process_params_dict(params))
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 406, in _process_params_dict
) from err
mysql.connector.errors.ProgrammingError: Failed processing pyformat-parameters; Python 'taskinstancestate' cannot be converted to a MySQL type
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/bin/airflow", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/site-packages/airflow/__main__.py", line 48, in main
args.func(args)
File "/usr/local/lib/python3.6/site-packages/airflow/cli/cli_parser.py", line 48, in command
return func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/airflow/utils/cli.py", line 92, in wrapper
return f(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/airflow/cli/commands/scheduler_command.py", line 75, in scheduler
_run_scheduler_job(args=args)
File "/usr/local/lib/python3.6/site-packages/airflow/cli/commands/scheduler_command.py", line 46, in _run_scheduler_job
job.run()
File "/usr/local/lib/python3.6/site-packages/airflow/jobs/base_job.py", line 242, in run
session.commit()
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 1046, in commit
self.transaction.commit()
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 504, in commit
self._prepare_impl()
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 483, in _prepare_impl
self.session.flush()
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2540, in flush
self._flush(objects)
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2682, in _flush
transaction.rollback(_capture_exception=True)
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
with_traceback=exc_tb,
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
raise exception
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2642, in _flush
flush_context.execute()
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
rec.execute(self)
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 589, in execute
uow,
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 245, in save_obj
insert,
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 1136, in _emit_insert_statements
statement, params
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1011, in execute
return meth(self, multiparams, params)
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1130, in _execute_clauseelement
distilled_params,
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1317, in _execute_context
e, statement, parameters, cursor, context
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1511, in _handle_dbapi_exception
sqlalchemy_exception, with_traceback=exc_info[2], from_=e
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
raise exception
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1277, in _execute_context
cursor, statement, parameters, context
File "/usr/local/lib64/python3.6/site-packages/sqlalchemy/engine/default.py", line 608, in do_execute
cursor.execute(statement, parameters)
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 541, in execute
stmt = _bytestr_format_dict(stmt, self._process_params_dict(params))
File "/usr/local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 406, in _process_params_dict
) from err
sqlalchemy.exc.ProgrammingError: (mysql.connector.errors.ProgrammingError) Failed processing pyformat-parameters; Python 'taskinstancestate' cannot be converted to a MySQL type
[SQL: INSERT INTO job (dag_id, state, job_type, start_date, end_date, latest_heartbeat, executor_class, hostname, unixname) VALUES (%(dag_id)s, %(state)s, %(job_type)s, %(start_date)s, %(end_date)s, %(latest_heartbeat)s, %(executor_class)s, %(hostname)s, %(unixname)s)]
[parameters: {'dag_id': None, 'state': <TaskInstanceState.RUNNING: 'running'>, 'job_type': 'SchedulerJob', 'start_date': datetime.datetime(2022, 9, 14, 18, 43, 29, 247880), 'end_date': None, 'latest_heartbeat': datetime.datetime(2022, 9, 14, 18, 43, 29, 247894), 'executor_class': 'LocalExecutor', 'hostname': 'airhost', 'unixname': 'root'}]
(Background on this error at: http://sqlalche.me/e/13/f405)
I have been clueless about this section:
"msql.connector.errors.ProgrammingError: Failed processing pyformat-parameters; Python 'taskinstancestate' cannot be converted to a MySQL type".
What does that mean? Any ideas? I haven't run any DAGs or built anything so far.
I managed to fix this. The problem was related to the driver mysqlconnector chosen for 'sql_alchemy_conn' string. I switched to pymysql and the problem was solved:
mysql+pymysql://airflow_user:airflow_password#localhost:3306/airflow_db
there are two existing IoT agents in our application, one is iotagent-ul(over HTTP), another is lwm2m-iotagent(over HTTP). Recently in order to integrate new sensors, I need to add a new iotagent-json(over MQTT). After bringing up the system, there is some strange error log as I pasted at the end:
(1) iotagent-ul is over HTTP, IOTA_DEFAULT_TRANSPORT is not defined in iotagent-ul, just use the default value HTTP, but iotagent-ul always complains that "Couldn't connect with MQTT broker" and "Error: Callback was already called", why will iotagent-ul try to connect MQTT broker?
(2) iotagent-json is defined with IOTA_DEFAULT_TRANSPORT=MQTT, but it also reports a error for IOTAJSON.AMQP.Binding, should I just ignore it?
These containers can run up, but an endless error log is thrown out in the console. BTW, before adding the new iotagent-json, these two previous iotagent-ul and lwm2m-iotagent can work properly.
Could you help me view the error info and the IoT agents definition in yml? Any comments are appreciated, thank you very much.
1 The services defined in docker-compose.yml file:
# IoT Agents ##################################################################
iot-agent-ul:
image: fiware/iotagent-ul
hostname: iot-agent-ul
container_name: fiware-iot-agent-ul
depends_on:
- mongo-db
networks:
- default
expose:
- "4041"
- "7896"
ports:
- "4041:4041"
- "7896:7896"
environment:
- "IOTA_CB_HOST=orion" # name of the context broker to update context
- "IOTA_CB_PORT=1026" # port the context broker listens on to update context
- "IOTA_CB_NGSI_VERSION=v2" # NGSI version to use
- "IOTA_NORTH_PORT=4041" # port for devices provisioning
- "IOTA_REGISTRY_TYPE=mongodb" #Whether to hold IoT device info in memory or in a database
- "IOTA_LOG_LEVEL=ERROR" #The log level of the IoT Agent
- "IOTA_TIMESTAMP=true" # whether to include or not the timestamp
- "IOTA_MONGO_HOST=mongo-db" # The host name of MongoDB
- "IOTA_MONGO_PORT=27017" # The port mongoDB is listening on
- "IOTA_MONGO_DB=iotagentul" # The name of the database used in mongoDB
- "IOTA_HTTP_PORT=7896" # The port used for device traffic over HTTP
- "IOTA_PROVIDER_URL=http://iot-agent-ul:4041" # URL of the agent
- "IOTA_AUTOCAST=true" # autocasting of values into NGSI standard
iot-agent-lwm2m:
image: hopu/lwm2m-iotagent:observe-and-read
hostname: iot-agent-lwm2m
container_name: fiware-iot-agent-lwm2m
expose:
- "4042"
- "5683"
ports:
- "4042:4042"
- "5683:5683/udp"
environment:
- "IOTA_CB_HOST=orion" # name of the context broker to update context
- "IOTA_CB_PORT=1026" # port the context broker listens on to update context
- "IOTA_NORTH_PORT=4042" # port for devices provisioning
- "IOTA_REGISTRY_TYPE=mongodb" # whether to hold IoT device info in memory or in a database
- "IOTA_LOG_LEVEL=ERROR" #The log level of the IoT Agent
- "IOTA_TIMESTAMP=true" # whether to include or not the timestamp
- "IOTA_MONGO_HOST=mongo-db" # The host name of MongoDB
- "IOTA_MONGO_PORT=27017" # The port mongoDB is listening on
- "IOTA_MONGO_DB=iotagentlwm2m" # The name of the database used in mongoDB
- "IOTA_HTTP_PORT=5683" # The port used for device traffic over HTTP
- "IOTA_PROVIDER_URL=http://iot-agent-lwm2m:4042" # URL of the agent
- "IOTA_AUTOCAST=true" # autocasting of values into NGSI standard
volumes:
- "./iota-lwm2m/config.js:/opt/iota-lwm2m/config.js"
- "./iota-lwm2m/omaRegistry.json:/opt/iota-lwm2m/omaRegistry.json"
- "./iota-lwm2m/omaInverseRegistry.json:/opt/iota-lwm2m/omaInverseRegistry.json"
restart: on-failure
depends_on:
- mongo-db
- orion
networks:
- default
iot-agent-json:
image: fiware/iotagent-json:latest
hostname: iot-agent-json
container_name: fiware-iot-agent-json
depends_on:
- mongo-db
- mosquitto
expose:
- "4043"
- "7896" # No traffic,7896 is the http listening port for sensors
ports:
- "4043:4043"
- "7898:7898" # No traffic
environment:
- "IOTA_CB_HOST=orion" # name of the context broker to update context
- "IOTA_CB_PORT=1026" # port the context broker listens on to update context
- "IOTA_NORTH_PORT=4043" # port for devices provisioning
- "IOTA_REGISTRY_TYPE=mongodb" # Whether to hold IoT device info in memory or in a database
- "IOTA_LOG_LEVEL=DEBUG" # The log level of the IoT Agent
- "IOTA_TIMESTAMP=true" # whether to include or not the timestamp
- "IOTA_CB_NGSI_VERSION=v2" # NGSI version to use
- "IOTA_AUTOCAST=true" # autocasting of values into NGSI standard
- "IOTA_MONGO_HOST=mongo-db" # The host name of MongoDB
- "IOTA_MONGO_PORT=27017" # The port mongoDB is listening on
- "IOTA_MONGO_DB=iotagentjson" # The name of the database used in mongoDB
- "IOTA_HTTP_PORT=7898" # The port used for device traffic over HTTP
- "IOTA_PROVIDER_URL=http://iot-agent:4043" # URL of the agent
- "IOTA_DEFAULT_RESOURCE=/iot/json" # IOTA_PROVIDER_URL, the default path the IoT Agent uses listening for JSON measures over HTTP.
- "IOTA_MQTT_HOST=mosquitto" # MQTT broker service
- "IOTA_MQTT_PORT=1883" # MQTT service port
- "IOTA_DEFAULT_TRANSPORT=MQTT" # ---
- "IOTA_MQTT_USERNAME=myusername"
- "IOTA_MQTT_PASSWORD=mypassword"
networks:
- default
2 After docker containers start-up, some error log printed out:
fiware-iot-agent-ul | time=2022-08-23T09:19:32.404Z | lvl=ERROR | corr=650cc5a7-e0b0-406a-bb7d-84db422bb0e3 | trans=650cc5a7-e0b0-406a-bb7d-84db422bb0e3 | op=IOTAUL.AMQP.Binding | from=n/a | srv=n/a | subsrv=n/a | msg=connect ECONNREFUSED 127.0.0.1:5672 | comp=IoTAgent
fiware-iot-agent-ul | time=2022-08-23T09:19:32.405Z | lvl=FATAL | corr=650cc5a7-e0b0-406a-bb7d-84db422bb0e3 | trans=650cc5a7-e0b0-406a-bb7d-84db422bb0e3 | op=IoTAgentNGSI.ContextServer | from=n/a | srv=n/a | subsrv=n/a | msg=GLOBAL-002: Couldn't connect with MQTT broker: {"errno":-111,"code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":1883} | comp=IoTAgent
fiware-iot-agent-ul | time=2022-08-23T09:19:32.409Z | lvl=ERROR | corr=n/a | trans=n/a | op=IoTAgentNGSI.DomainControl | from=n/a | srv=n/a | subsrv=n/a | msg=Error: Callback was already called.
fiware-iot-agent-ul | at /opt/iotaul/node_modules/async/dist/async.js:969:32
fiware-iot-agent-ul | at MqttClient.<anonymous> (/opt/iotaul/lib/bindings/MQTTBinding.js:375:17)
fiware-iot-agent-ul | at MqttClient.emit (node:events:539:35)
fiware-iot-agent-ul | at MqttClient.emit (node:domain:475:12)
fiware-iot-agent-ul | at Socket.streamErrorHandler (/opt/iotaul/node_modules/mqtt/lib/client.js:460:12)
fiware-iot-agent-ul | at Socket.emit (node:events:527:28)
fiware-iot-agent-ul | at Socket.emit (node:domain:475:12)
fiware-iot-agent-ul | at emitErrorNT (node:internal/streams/destroy:157:8)
fiware-iot-agent-ul | at emitErrorCloseNT (node:internal/streams/destroy:122:3)
fiware-iot-agent-ul | at processTicksAndRejections (node:internal/process/task_queues:83:21) {
fiware-iot-agent-ul | domainThrown: true
fiware-iot-agent-ul | } | comp=IoTAgent
fiware-iot-agent-ul | time=2022-08-23T09:19:33.425Z | lvl=FATAL | corr=n/a | trans=n/a | op=n/a | from=n/a | srv=n/a | subsrv=n/a | msg=GLOBAL-002: Couldn't connect with MQTT broker: {"errno":-111,"code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":1883} | comp=IoTAgent
fiware-iot-agent-ul | time=2022-08-23T09:19:33.426Z | lvl=FATAL | corr=n/a | trans=n/a | op=IoTAgentNGSI.Global | from=n/a | srv=n/a | subsrv=n/a | msg=An unexpected exception has been raised. Ignoring: Error: Callback was already called.
fiware-iot-agent-ul | at /opt/iotaul/node_modules/async/dist/async.js:969:32
fiware-iot-agent-ul | at MqttClient.<anonymous> (/opt/iotaul/lib/bindings/MQTTBinding.js:375:17)
fiware-iot-agent-ul | at MqttClient.emit (node:events:539:35)
fiware-iot-agent-ul | at MqttClient.emit (node:domain:475:12)
fiware-iot-agent-ul | at Socket.streamErrorHandler (/opt/iotaul/node_modules/mqtt/lib/client.js:460:12)
fiware-iot-agent-ul | at Socket.emit (node:events:527:28)
fiware-iot-agent-ul | at Socket.emit (node:domain:475:12)
fiware-iot-agent-ul | at emitErrorNT (node:internal/streams/destroy:157:8)
fiware-iot-agent-ul | at emitErrorCloseNT (node:internal/streams/destroy:122:3)
fiware-iot-agent-ul | at processTicksAndRejections (node:internal/process/task_queues:83:21) | comp=IoTAgent
fiware-iot-agent-json | time=2022-08-23T09:19:35.473Z | lvl=INFO | corr=76c65807-e6f8-4ed0-ab3c-ead581e9d6bd | trans=76c65807-e6f8-4ed0-ab3c-ead581e9d6bd | op=IOTAJSON.MQTT.Binding | from=n/a | srv=n/a | subsrv=n/a | msg=connected | comp=IoTAgent
fiware-iot-agent-json | time=2022-08-23T09:19:35.486Z | lvl=ERROR | corr=76c65807-e6f8-4ed0-ab3c-ead581e9d6bd | trans=76c65807-e6f8-4ed0-ab3c-ead581e9d6bd | op=IOTAJSON.AMQP.Binding | from=n/a | srv=n/a | subsrv=n/a | msg=connect ECONNREFUSED 127.0.0.1:5672 | comp=IoTAgent
. ____ _ __ _ _
/\ / ' __ _ ()_ __ __ _ \ \ \ \
( ( )_ | '_ | '| | ' / ` | \ \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
' |____| .|| ||| |__, | / / / /
=========|_|==============|___/=///_/
:: Spring Boot :: (v1.4.3.RELEASE)
2017-05-09 22:31:48.424 INFO 10820 --- [ restartedMain] com.bearmom.app.AppServiceApplication : Starting AppServiceApplication on TheKing with PID 10820 (F:\bearmon-app-service\target\classes started by King in E:\workspace_idea\code)
[2017-05-09 22:31:48.424] INFO com.bearmom.app.AppServiceApplication - Starting AppServiceApplication on TheKing with PID 10820 (F:\bearmon-app-service\target\classes started by King in E:\workspace_idea\code)
2017-05-09 22:31:48.443 INFO 10820 --- [ restartedMain] com.bearmom.app.AppServiceApplication : The following profiles are active: dev
[2017-05-09 22:31:48.443] INFO com.bearmom.app.AppServiceApplication - The following profiles are active: dev
2017-05-09 22:31:53.297 INFO 10820 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#598b4233: startup date [Tue May 09 22:31:53 CST 2017]; root of context hierarchy
[2017-05-09 22:31:53.297] INFO o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#598b4233: startup date [Tue May 09 22:31:53 CST 2017]; root of context hierarchy
2017-05-09 22:31:59.576 INFO 10820 --- [ restartedMain] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [spring-context-web.xml]
[2017-05-09 22:31:59.576] INFO o.s.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring-context-web.xml]
2017-05-09 22:32:00.524 INFO 10820 --- [ restartedMain] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [spring-mybatis.xml]
[2017-05-09 22:32:00.524] INFO o.s.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring-mybatis.xml]
2017-05-09 22:32:00.776 INFO 10820 --- [ restartedMain] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [spring-redis.xml]
[2017-05-09 22:32:00.776] INFO o.s.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring-redis.xml]
2017-05-09 22:32:00.834 INFO 10820 --- [ restartedMain] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [spring-oss.xml]
[2017-05-09 22:32:00.834] INFO o.s.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring-oss.xml]
2017-05-09 22:32:01.544 WARN 10820 --- [ restartedMain] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.bearmom.app]' package. Please check your configuration.
[2017-05-09 22:32:01.544] WARN org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.bearmom.app]' package. Please check your configuration.
[enter image description here][1]
[1]: https://i.stack.imgur.com/8AFKb.pngenter code here
I have an issue where the BashOperator is not logging all of the output from wget. It'll log only the first 1-5 lines of the output.
I have tried this with only wget as the bash command:
tester = BashOperator(
task_id = 'testing',
bash_command = "wget -N -r -nd --directory-prefix='/tmp/' http://apache.cs.utah.edu/httpcomponents/httpclient/source/httpcomponents-client-4.5.3-src.zip",
dag = dag)
I've also tried this as part of a longer bash script that has other commands that follow wget. Airflow does wait for the script to complete before firing downstream tasks. Here's an example bash script:
#!/bin/bash
echo "Starting up..."
wget -N -r -nd --directory-prefix='/tmp/' http://apache.cs.utah.edu/httpcomponents/httpclient/source/httpcomponents-client-4.5.3-src.zip
echo "Download complete..."
unzip /tmp/httpcomponents-client-4.5.3-src.zip -o -d /tmp/test_airflow
echo "Archive unzipped..."
Last few lines of a log file:
[2017-04-13 18:33:34,214] {base_task_runner.py:95} INFO - Subtask: --------------------------------------------------------------------------------
[2017-04-13 18:33:34,214] {base_task_runner.py:95} INFO - Subtask: Starting attempt 1 of 1
[2017-04-13 18:33:34,215] {base_task_runner.py:95} INFO - Subtask: --------------------------------------------------------------------------------
[2017-04-13 18:33:34,215] {base_task_runner.py:95} INFO - Subtask:
[2017-04-13 18:33:35,068] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:33:35,068] {models.py:1342} INFO - Executing <Task(BashOperator): testing> on 2017-04-13 18:33:08
[2017-04-13 18:33:37,569] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:33:37,569] {bash_operator.py:71} INFO - tmp dir root location:
[2017-04-13 18:33:37,569] {base_task_runner.py:95} INFO - Subtask: /tmp
[2017-04-13 18:33:37,571] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:33:37,571] {bash_operator.py:81} INFO - Temporary script location :/tmp/airflowtmpqZhPjB//tmp/airflowtmpqZhPjB/testingCkJgDE
[2017-04-13 18:14:54,943] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:54,942] {bash_operator.py:82} INFO - Running command: /var/www/upstream/xtractor/scripts/Temp_test.sh
[2017-04-13 18:14:54,951] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:54,950] {bash_operator.py:91} INFO - Output:
[2017-04-13 18:14:54,955] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:54,954] {bash_operator.py:96} INFO - Starting up...
[2017-04-13 18:14:54,958] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:54,957] {bash_operator.py:96} INFO - --2017-04-13 18:14:54-- http://apache.cs.utah.edu/httpcomponents/httpclient/source/httpcomponents-client-4.5.3-src.zip
[2017-04-13 18:14:55,106] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:55,105] {bash_operator.py:96} INFO - Resolving apache.cs.utah.edu (apache.cs.utah.edu)... 155.98.64.87
[2017-04-13 18:14:55,186] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:55,186] {bash_operator.py:96} INFO - Connecting to apache.cs.utah.edu (apache.cs.utah.edu)|155.98.64.87|:80... connected.
[2017-04-13 18:14:55,284] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:55,284] {bash_operator.py:96} INFO - HTTP request sent, awaiting response... 200 OK
[2017-04-13 18:14:55,285] {base_task_runner.py:95} INFO - Subtask: [2017-04-13 18:14:55,284] {bash_operator.py:96} INFO - Length: 1662639 (1.6M) [application/zip]
[2017-04-13 18:15:01,485] {jobs.py:2083} INFO - Task exited with return code 0
Edit: More testing suggests that it's a problem logging the output of wget.
Its because in the default operator only last line is printed. Please replace the code with the following inside airflow/operators/bash_operator.py where ever your airflow is installed. Usually, you need to look in where your python is and then go to site-packages
from builtins import bytes
import os
import signal
import logging
from subprocess import Popen, STDOUT, PIPE
from tempfile import gettempdir, NamedTemporaryFile
from airflow.exceptions import AirflowException
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults
from airflow.utils.file import TemporaryDirectory
class BashOperator(BaseOperator):
"""
Execute a Bash script, command or set of commands.
:param bash_command: The command, set of commands or reference to a
bash script (must be '.sh') to be executed.
:type bash_command: string
:param xcom_push: If xcom_push is True, the last line written to stdout
will also be pushed to an XCom when the bash command completes.
:type xcom_push: bool
:param env: If env is not None, it must be a mapping that defines the
environment variables for the new process; these are used instead
of inheriting the current process environment, which is the default
behavior. (templated)
:type env: dict
:type output_encoding: output encoding of bash command
"""
template_fields = ('bash_command', 'env')
template_ext = ('.sh', '.bash',)
ui_color = '#f0ede4'
#apply_defaults
def __init__(
self,
bash_command,
xcom_push=False,
env=None,
output_encoding='utf-8',
*args, **kwargs):
super(BashOperator, self).__init__(*args, **kwargs)
self.bash_command = bash_command
self.env = env
self.xcom_push_flag = xcom_push
self.output_encoding = output_encoding
def execute(self, context):
"""
Execute the bash command in a temporary directory
which will be cleaned afterwards
"""
bash_command = self.bash_command
logging.info("tmp dir root location: \n" + gettempdir())
line_buffer = []
with TemporaryDirectory(prefix='airflowtmp') as tmp_dir:
with NamedTemporaryFile(dir=tmp_dir, prefix=self.task_id) as f:
f.write(bytes(bash_command, 'utf_8'))
f.flush()
fname = f.name
script_location = tmp_dir + "/" + fname
logging.info("Temporary script "
"location :{0}".format(script_location))
logging.info("Running command: " + bash_command)
sp = Popen(
['bash', fname],
stdout=PIPE, stderr=STDOUT,
cwd=tmp_dir, env=self.env,
preexec_fn=os.setsid)
self.sp = sp
logging.info("Output:")
line = ''
for line in iter(sp.stdout.readline, b''):
line = line.decode(self.output_encoding).strip()
line_buffer.append(line)
logging.info(line)
sp.wait()
logging.info("Command exited with "
"return code {0}".format(sp.returncode))
if sp.returncode:
raise AirflowException("Bash command failed")
logging.info("\n".join(line_buffer))
if self.xcom_push_flag:
return "\n".join(line_buffer)
def on_kill(self):
logging.info('Sending SIGTERM signal to bash process group')
os.killpg(os.getpgid(self.sp.pid), signal.SIGTERM)
This isn't a complete answer, but it's a big step forward. The problem seems to be an issue with Python's logging function and the output wget produces. Turns out the airflow scheduler was throwing an error: UnicodeEncodeError: 'ascii' codec can't encode character u'\u2018' in position....
I modified bash_operator.py in the airflow code base so that the bash output is encoded (on line 95):
loging.info(line.encode('utf-8'))
An error is still happening but at least it is appearing in the log file along with the output of the rest of the bash script. The error that appears in the log file now is: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position...
Even though there is still a Python error happening, output is getting logged, so I'm satisfied for now. If someone has an idea of how to resolve this issue in a better manner, I'm open to ideas.