def on_modified(self, _): """Callback invoked when the file is modified This captures all other modification events that occur against the file """ if self.modify_event: publish(self.modify_event)
def post(self): """ --- summary: Publish a new event parameters: - name: bg-namespace in: header required: false description: Namespace to use type: string - name: event in: body description: The the Event object schema: $ref: '#/definitions/Event' responses: 204: description: An Event has been published 400: $ref: '#/definitions/400Error' 50x: $ref: '#/definitions/50xError' tags: - Event """ publish(SchemaParser.parse_event(self.request.decoded_body, from_string=True)) self.set_status(204)
def on_moved(self, _): """Callback invoked when the file is moved This captures if the file is moved into or from the directory """ if self.moved_event: publish(self.moved_event)
async def shutdown(): """Do shutdown things This still operates within the ioloop, so stopping it should be the last thing done. Because things in startup aren't guaranteed to have been run we need to be careful about checking to make sure things actually need to be shut down. This execution is normally scheduled by the signal handler. """ logger.debug("Stopping server for new HTTP connections") server.stop() logger.debug("Stopping forward processing") beer_garden.router.forward_processor.stop() # This will almost definitely not be published to the websocket, because it would # need to make it up to the main process and back down into this process. We just # publish this here in case the main process is looking for it. publish( Event(name=Events.ENTRY_STOPPED.name, metadata={"entry_point_type": "HTTP"}) ) # We need to do this before the scheduler shuts down completely in order to kick any # currently waiting request creations logger.debug("Closing all open HTTP connections") await server.close_all_connections() logger.debug("Stopping IO loop") io_loop.add_callback(io_loop.stop)
def on_deleted(self, _): """Callback invoked when the file is deleted This captures if the file was deleted (be warned that VIM does this by default during write actions) """ if self.deleted_event: publish(self.deleted_event)
def on_created(self, _): """Callback invoked when the file is created When a user VIM edits a file it DELETES, then CREATES the file, this captures that case """ if self.create_event: publish(self.create_event)
def run(ep_conn): conn_manager = StompManager(ep_conn) _setup_event_handling(conn_manager) _setup_operation_forwarding() entry_config = config.get("entry.stomp") parent_config = config.get("parent.stomp") garden_name = config.get("garden.name") if entry_config.get("enabled"): conn_manager.add_connection(stomp_config=entry_config, name=f"{garden_name}_entry", is_main=True) if parent_config.get("enabled"): conn_manager.add_connection(stomp_config=parent_config, name=f"{garden_name}_parent", is_main=True) for garden in get_gardens(include_local=False): if garden.name != garden_name and garden.connection_type: if garden.connection_type.casefold() == "stomp": connection_params = garden.connection_params.get("stomp", {}) connection_params["send_destination"] = None conn_manager.add_connection(stomp_config=connection_params, name=garden.name) conn_manager.start() logger.info("Stomp entry point started") publish( Event(name=Events.ENTRY_STARTED.name, metadata={"entry_point_type": "STOMP"})) while not shutdown_event.wait(10): for name, info in conn_manager.conn_dict.items(): connection = info.get("conn") if connection: logger.debug(f"{name}: Checking connection") if not connection.is_connected(): logger.debug(f"{name}: Attempting to reconnect") if connection.connect(): logger.debug(f"{name}: Reconnect successful") else: logger.debug(f"{name}: Reconnect failed") conn_manager.shutdown() conn_manager.stop() conn_manager.join(5) logger.debug("Stopping forward processing") beer_garden.router.forward_processor.stop()
def rescan(*args, **kwargs) -> List[Runner]: """Scans plugin directory and starts any new runners""" new_runners = lpm_proxy.scan_path(*args, **kwargs) for runner in new_runners: publish( Event( name=Events.RUNNER_STARTED.name, payload_type=Runner.__name__, payload=runner, ) ) return new_runners
def shutdown(self): self.logger.debug("Disconnecting connections") for value in self.conn_dict.values(): value["conn"].disconnect() # This will almost definitely not be published because # it would need to make it up to the main process and # back down into this process. We just publish this # here in case the main process is looking for it. publish( Event( name=Events.ENTRY_STOPPED.name, metadata={"entry_point_type": "STOMP"}, ), )
async def startup(): """Do startup things. This is the first thing called from within the ioloop context. """ global anonymous_principal http_config = config.get("entry.http") logger.debug( f"Starting HTTP server on {http_config.host}:{http_config.port}") server.listen(http_config.port, http_config.host) logger.info("Http entry point started") publish( Event(name=Events.ENTRY_STARTED.name, metadata={"entry_point_type": "HTTP"}))
def _publish_failed_forward(operation: Operation = None, error_message: str = None, event_name: str = None): if operation.operation_type == "REQUEST_CREATE": complete_request( operation.model.id, status="ERROR", output=error_message, error_class=event_name, ) publish( Event( name=event_name, payload_type="Operation", payload=operation, error_message=error_message, )) raise RoutingRequestException(error_message)
async def startup(): """Do startup things. This is the first thing called from within the ioloop context. """ global anonymous_principal # Need to wait until after mongo connection established to load anonymous_principal = load_anonymous() http_config = config.get("entry.http") logger.debug(f"Starting HTTP server on {http_config.host}:{http_config.port}") server.listen(http_config.port, http_config.host) logger.debug("Starting forward processor") beer_garden.router.forward_processor.start() beer_garden.api.http.logger.info("Http entry point is started. Hello!") publish( Event(name=Events.ENTRY_STARTED.name, metadata={"entry_point_type": "HTTP"}) )
def rescan(*args, **kwargs) -> List[Runner]: """Scan plugin directory and start any new runners. Args: *args: Arguments to pass to ``scan_path`` in the PluginManager object. **kwargs: Keyword arguments to pass to ``scan_path`` in the PluginManager object. Returns: A list of the new runners """ new_runners = lpm_proxy.scan_path(*args, **kwargs) for the_runner in new_runners: publish( Event( name=Events.RUNNER_STARTED.name, payload_type=Runner.__name__, payload=the_runner, )) return new_runners
def forward(operation: Operation): """Forward the operation to a child garden Intended to be called in the context of an executor or processor. Args: operation: The operation to forward Returns: The result of the specific forward transport function used Raises: RoutingRequestException: Could not determine a route to child UnknownGardenException: The specified target garden is unknown """ target_garden = gardens.get(operation.target_garden_name) if not target_garden: target_garden = get_garden(operation.target_garden_name) try: if not target_garden: raise UnknownGardenException( f"Unknown child garden {operation.target_garden_name}") if not target_garden.connection_type: raise RoutingRequestException( "Attempted to forward operation to garden " f"'{operation.target_garden_name}' but the connection type was None. " "This probably means that the connection to the child garden has not " "been configured.") if target_garden.connection_type.casefold() == "http": return _forward_http(operation, target_garden) elif target_garden.connection_type.casefold() == "stomp": return _forward_stomp(operation, target_garden) else: raise RoutingRequestException( f"Unknown connection type {target_garden.connection_type}") except ForwardException as ex: error_message = str(ex) operation = ex.operation if operation.operation_type == "REQUEST_CREATE": complete_request( operation.model.id, status="ERROR", output=error_message, error_class=ex.event_name, ) # Publish an event publish( Event( name=ex.event_name, payload_type="Operation", payload=operation, error_message=error_message, )) raise
def handle_event(event): """Handle garden-related events For GARDEN events we only care about events originating from downstream. We also only care about immediate children, not grandchildren. Whenever a garden event is detected we should update that garden's database representation. This method should NOT update the routing module. Let its handler worry about that! """ if event.garden != config.get("garden.name"): if event.name in ( Events.GARDEN_STARTED.name, Events.GARDEN_UPDATED.name, Events.GARDEN_STOPPED.name, Events.GARDEN_SYNC.name, ): # Only do stuff for direct children if event.payload.name == event.garden: try: existing_garden = get_garden(event.payload.name) except DoesNotExist: existing_garden = None for system in event.payload.systems: system.local = False if existing_garden is None: event.payload.connection_type = None event.payload.connection_params = {} garden = create_garden(event.payload) else: for attr in ("status", "status_info", "namespaces", "systems"): setattr(existing_garden, attr, getattr(event.payload, attr)) garden = update_garden(existing_garden) # Publish update events for UI to dynamically load changes for Systems for system in garden.systems: publish( Event( name=Events.SYSTEM_UPDATED.name, garden=event.garden, payload_type="System", payload=system, )) elif event.name == Events.GARDEN_UNREACHABLE.name: target_garden = get_garden(event.payload.target_garden_name) if target_garden.status not in [ "UNREACHABLE", "STOPPED", "BLOCKED", "ERROR", ]: update_garden_status(event.payload.target_garden_name, "UNREACHABLE") elif event.name == Events.GARDEN_ERROR.name: target_garden = get_garden(event.payload.target_garden_name) if target_garden.status not in [ "UNREACHABLE", "STOPPED", "BLOCKED", "ERROR", ]: update_garden_status(event.payload.target_garden_name, "ERROR") elif event.name == Events.GARDEN_NOT_CONFIGURED.name: target_garden = get_garden(event.payload.target_garden_name) if target_garden.status == "NOT_CONFIGURED": update_garden_status(event.payload.target_garden_name, "NOT_CONFIGURED")