def _test_h_request_insufficient_cores(self): broker = self.get_broker() controller = self.get_controller() policy = broker.get_policy() policy.allocation_horizon = 10 clock = broker.get_actor_clock() proxy = ClientCallbackHelper(name=controller.get_name(), guid=controller.get_guid()) broker_callback = ClientCallbackHelper(name=broker.get_name(), guid=broker.get_guid()) ActorRegistrySingleton.get().register_callback(callback=proxy) ActorRegistrySingleton.get().register_callback( callback=broker_callback) slice_obj = SliceFactory.create(slice_id=ID(), name="inventory_slice") slice_obj.set_inventory(value=True) source = self.get_source_delegation(self.broker, slice_obj) self.broker.register_slice(slice_object=slice_obj) self.broker.register_delegation(delegation=source) self.broker.donate_delegation(delegation=source) cycle = 1 broker.external_tick(cycle=cycle) cycle += 1 start = clock.cycle_start_date(cycle=self.DonateStartCycle) end = clock.cycle_end_date(cycle=self.DonateEndCycle - 1) sliver = self.build_sliver_with_components() caphint = CapacityHints(instance_type="fabric.c64.m384.d4000") sliver.set_capacity_hints(caphint=caphint) request = self.get_reservation_for_network_node(start, end, sliver=sliver) broker.ticket(reservation=request, callback=proxy, caller=proxy.get_identity()) self.assertEqual(proxy.prepared, 0) self.assertEqual(proxy.called, 0) for c in range(cycle, self.DonateEndCycle): broker.external_tick(cycle=c) while broker.get_current_cycle() != c: time.sleep(0.001) while proxy.prepared != 1: time.sleep(0.001) self.assert_failed(request) self.assertEqual(1, proxy.prepared) if proxy.called > 0: print("Proxy Called") # self.assert_failed(proxy.get_reservation(), proxy.update_data) broker.await_no_pending_reservations() self.assertEqual(1, proxy.get_called()) self.assertTrue(request.is_closed())
def add_slice(self, *, slice_obj: SliceAvro, caller: AuthToken, id_token: str = None) -> ResultStringAvro: result = ResultStringAvro() result.status = ResultAvro() if slice_obj is None or caller is None: result.status.set_code(ErrorCodes.ErrorInvalidArguments.value) result.status.set_message( ErrorCodes.ErrorInvalidArguments.interpret()) else: try: user_dn = None user_email = None if id_token is not None: fabric_token = AccessChecker.check_access( action_id=ActionId.query, resource_type=ResourceType.slice, token=id_token, logger=self.logger, actor_type=self.actor.get_type(), resource_id=str(slice_obj.slice_name)) user_dn = fabric_token.get_decoded_token().get( Constants.CLAIMS_SUB, None) user_email = fabric_token.get_decoded_token().get( Constants.CLAIMS_EMAIL, None) if user_dn is None: result.status.set_code( ErrorCodes.ErrorInvalidToken.value) result.status.set_message( ErrorCodes.ErrorInvalidToken.interpret()) return result slice_obj_new = SliceFactory.create( slice_id=ID(), name=slice_obj.get_slice_name()) slice_obj_new.set_description( description=slice_obj.get_description()) slice_obj_new.set_owner(owner=self.actor.get_identity()) slice_obj_new.get_owner().set_oidc_sub_claim( oidc_sub_claim=user_dn) slice_obj_new.get_owner().set_email(email=user_email) slice_obj_new.set_graph_id(graph_id=slice_obj.graph_id) slice_obj_new.set_config_properties( value=slice_obj.get_config_properties()) slice_obj_new.set_lease_end( lease_end=slice_obj.get_lease_end()) slice_obj_new.set_lease_start(lease_start=datetime.utcnow()) if slice_obj.get_inventory(): slice_obj_new.set_inventory(value=True) elif slice_obj.is_broker_client_slice(): slice_obj.set_broker_client_slice(value=True) elif slice_obj.is_client_slice(): slice_obj.set_client_slice(value=True) class Runner(ABCActorRunnable): def __init__(self, *, actor: ABCActorMixin): self.actor = actor def run(self): try: self.actor.register_slice( slice_object=slice_obj_new) except Exception as e: self.actor.get_plugin().release_slice( slice_obj=slice_obj_new) raise e return None self.actor.execute_on_actor_thread_and_wait(runnable=Runner( actor=self.actor)) result.set_result(str(slice_obj_new.get_slice_id())) except Exception as e: self.logger.error("add_slice: {}".format(e)) result.status.set_code(ErrorCodes.ErrorInternalError.value) result.status.set_message( ErrorCodes.ErrorInternalError.interpret(exception=e)) result.status = ManagementObject.set_exception_details( result=result.status, e=e) return result
def test_d_extend_ticket(self): """ Requests a ticket for all resources. Checks if the ticket is allocated for what was asked. Checks the term. Checks whether the reservation is closed when it expires. Repeat one more time. """ broker = self.get_broker() controller = self.get_controller() clock = broker.get_actor_clock() proxy = ClientCallbackHelper(name=controller.get_name(), guid=controller.get_guid()) broker_callback = ClientCallbackHelper(name=broker.get_name(), guid=broker.get_guid()) ActorRegistrySingleton.get().register_callback(callback=proxy) ActorRegistrySingleton.get().register_callback( callback=broker_callback) last_called = proxy.get_called() inv_slice = SliceFactory.create(slice_id=ID(), name="inventory-slice") inv_slice.set_inventory(value=True) source = self.get_source_delegation(self.broker, inv_slice) self.broker.register_slice(slice_object=inv_slice) self.broker.register_delegation(delegation=source) self.broker.donate_delegation(delegation=source) cycle = 1 broker.external_tick(cycle=cycle) cycle += 1 units = 1 start = clock.cycle_start_date(cycle=self.DonateStartCycle) cycle_end = self.DonateEndCycle - 50 end = clock.cycle_end_date(cycle=cycle_end) sliver = self.build_sliver() request = self.get_reservation_for_network_node(start, end, sliver) reservation = request broker.ticket(reservation=request, callback=proxy, caller=proxy.get_identity()) for c in range(cycle, self.DonateEndCycle): broker.external_tick(cycle=c) while broker.get_current_cycle() != c: time.sleep(0.001) if last_called < proxy.get_called(): self.assert_ticketed(proxy.get_reservation(), units, request.get_type(), start, end) last_called = proxy.get_called() if c == cycle_end - 10: self.assertEqual(1, proxy.get_called()) start = ActorClock.from_milliseconds( milli_seconds=ActorClock.to_milliseconds(when=end) + 1) end = clock.cycle_end_date(cycle=self.DonateEndCycle - 1) request = self.get_request_from_request( request, units, request.get_type(), start, end) broker.extend_ticket(reservation=request, caller=proxy.get_identity()) print("Extend done") broker.await_no_pending_reservations() self.assertEqual(2, proxy.get_called()) self.assertTrue(reservation.is_closed())
def __init__(self): super().__init__() self.id = ID(uid=Constants.CONTAINER_MANAGMENT_OBJECT_ID)
def get_failed_reservation_id(self) -> ID(): """ Get failed reservation id @return failed reservation id """ return self.failed_reservation_id
def fill_client(*, client_mng: ClientMng) -> Client: result = Client() result.set_name(name=client_mng.get_name()) result.set_guid(guid=ID(uid=client_mng.get_guid())) return result
def renew_slice(self, *, token: str, slice_id: str, new_lease_end_time: str): """ Renew a slice :param token Fabric Identity Token :param slice_id Slice Id :param new_lease_end_time: New Lease End Time in UTC in '%Y-%m-%d %H:%M:%S' format :raises Raises an exception in case of failure :return: """ if self.globals.is_maintenance_mode_on(): raise OrchestratorException(Constants.MAINTENANCE_MODE_ERROR) failed_to_extend_rid_list = [] try: controller = self.controller_state.get_management_actor() self.logger.debug(f"renew_slice invoked for Controller: {controller}") slice_guid = None if slice_id is not None: slice_guid = ID(uid=slice_id) slice_list = controller.get_slices(id_token=token, slice_id=slice_guid) if slice_list is None or len(slice_list) == 0: raise OrchestratorException(f"Slice# {slice_id} not found", http_error_code=NOT_FOUND) slice_object = next(iter(slice_list)) slice_state = SliceState(slice_object.get_state()) if slice_state == SliceState.Dead or slice_state == SliceState.Closing: raise OrchestratorException(f"Slice# {slice_id} already closed", http_error_code=BAD_REQUEST) if slice_state != SliceState.StableOK and slice_state != SliceState.StableError: self.logger.info(f"Unable to renew Slice# {slice_guid} that is not yet stable, try again later") raise OrchestratorException(f"Unable to renew Slice# {slice_guid} that is not yet stable, " f"try again later") new_end_time = self.__validate_lease_end_time(lease_end_time=new_lease_end_time) reservations = controller.get_reservations(id_token=token, slice_id=slice_id) if reservations is None or len(reservations) < 1: if controller.get_last_error() is not None: self.logger.error(controller.get_last_error()) raise OrchestratorException(f"Slice# {slice_id} has no reservations") self.logger.debug(f"There are {len(reservations)} reservations in the slice# {slice_id}") for r in reservations: res_state = ReservationStates(r.get_state()) if res_state == ReservationStates.Closed or res_state == ReservationStates.Failed or \ res_state == ReservationStates.CloseWait: continue current_end_time = ActorClock.from_milliseconds(milli_seconds=r.get_end()) if new_end_time < current_end_time: raise OrchestratorException(f"Attempted new term end time is shorter than current slice end time") self.logger.debug(f"Extending reservation with reservation# {r.get_reservation_id()}") result = controller.extend_reservation(reservation=ID(uid=r.get_reservation_id()), new_end_time=new_end_time) if not result: failed_to_extend_rid_list.append(r.get_reservation_id()) else: slice_object.set_lease_end(lease_end=new_end_time) if not controller.update_slice(slice_obj=slice_object): self.logger.error(f"Failed to update lease end time: {new_end_time} in Slice: {slice_object}") return ResponseBuilder.get_response_summary(rid_list=failed_to_extend_rid_list) except Exception as e: self.logger.error(traceback.format_exc()) self.logger.error(f"Exception occurred processing renew e: {e}") raise e
def process_peer(self, *, peer: Peer): """ Process a peer @param peer peer @raises ConfigurationException in case of error """ from_guid = ID(uid=peer.get_guid()) from_type = ActorType.get_actor_type_from_string( actor_type=peer.get_type()) to_guid = self.actor.get_guid() to_type = self.actor.get_type() # We only like peers broker->site and orchestrator->broker # Reverse the peer if it connects site->broker or broker->orchestrator if from_type == ActorType.Authority and to_type == ActorType.Broker: from_guid, to_guid = to_guid, from_guid from_type, to_type = to_type, from_type if from_type == ActorType.Broker and to_type == ActorType.Orchestrator: from_guid, to_guid = to_guid, from_guid from_type, to_type = to_type, from_type if from_type == ActorType.Authority and to_type == ActorType.Orchestrator: from_guid, to_guid = to_guid, from_guid from_type, to_type = to_type, from_type # peers between actors of same type aren't allowed unless the actors are both brokers if from_type == to_type and from_type != ActorType.Broker: raise ConfigurationException( "Invalid peer type: broker can only talk to broker, orchestrator or site authority" ) container = ManagementUtils.connect(caller=self.actor.get_identity()) to_mgmt_actor = container.get_actor(guid=to_guid) self.logger.debug(f"to_mgmt_actor={to_mgmt_actor} to_guid={to_guid}") if to_mgmt_actor is None and container.get_last_error() is not None: self.logger.error(container.get_last_error()) from_mgmt_actor = container.get_actor(guid=from_guid) self.logger.debug( f"from_mgmt_actor={from_mgmt_actor} from_guid={from_guid}") if from_mgmt_actor is None and container.get_last_error() is not None: self.logger.error(container.get_last_error()) self.vertex_to_registry_cache(peer=peer) try: client = RemoteActorCacheSingleton.get().establish_peer( from_guid=from_guid, from_mgmt_actor=from_mgmt_actor, to_guid=to_guid, to_mgmt_actor=to_mgmt_actor) self.logger.debug(f"Client returned {client}") if client is not None: self.parse_exports(peer=peer, client=client, mgmt_actor=to_mgmt_actor) except Exception as e: raise ConfigurationException( f"Could not process exports from: {peer.get_guid()} to " f"{self.actor.get_guid()}. e= {e}")
def __init__(self): self.caller = None self.rtype = None self.message_id = ID() self.id_token = None
def _make_reservation(self, *, id: str): return ClientReservationFactory.create(rid=ID(uid=id))
class ControllerTestWrapper(Controller): broker_guid = ID() def bid(self): candidates = self.policy.formulate_bids(cycle=self.current_cycle) if candidates is not None: ticketing = candidates.get_ticketing() if ticketing is not None: for r in ticketing.values(): print("cycle: {} Ticket request for: {}".format( self.current_cycle, r)) if r.get_slice_name().startswith("fail"): already_failed = False slice_obj = r.get_slice() for slice_reservation in slice_obj.get_reservations( ).values(): if slice_reservation.get_state( ) == ReservationStates.Failed: already_failed = True break if not already_failed: self.fail_ticket(r) continue ticket = ResourceTicketFactory.create( issuer=self.broker_guid, units=r.get_approved_resources().get_units(), term=r.get_approved_term(), rtype=r.get_approved_type()) cs = Ticket(resource_ticket=ticket, plugin=self.get_plugin()) self.update_ticket_wrapper(r, r.get_approved_type(), r.get_approved_units(), cs, r.get_approved_term()) extending = candidates.get_extending() if extending is not None: for r in extending.values(): print("cycle: {} Extend Ticket request for: {}".format( self.current_cycle, r)) ticket = ResourceTicketFactory.create( issuer=self.broker_guid, units=r.get_approved_resources().get_units(), term=r.get_approved_term(), rtype=r.get_approved_type()) cs = Ticket(resource_ticket=ticket, plugin=self.get_plugin()) self.update_ticket_wrapper(r, r.get_approved_type(), r.get_approved_units(), cs, r.get_approved_term()) def close_expiring(self): rset = self.policy.get_closing(cycle=self.current_cycle) if rset is not None: for r in rset.values(): print("cycle: {} closing reservation r: {}".format( self.current_cycle, r)) r.transition(prefix="close", state=ReservationStates.Closed, pending=ReservationPendingStates.None_) def process_redeeming(self): rset = self.policy.get_redeeming(cycle=self.current_cycle) if rset is not None: for r in rset.values(): if r.get_state() == ReservationStates.Ticketed: print("cycle: {} redeeming reservation r: {}".format( self.current_cycle, r)) else: print("cycle: {} extending lease for reservation r: {}". format(self.current_cycle, r)) ticket = ResourceTicketFactory.create( issuer=self.broker_guid, units=r.resources.get_units(), term=r.term, rtype=r.resources.get_type()) cs = Ticket(resource_ticket=ticket, plugin=self.get_plugin()) self.update_lease_wrapper(r, r.get_approved_type(), r.get_approved_units(), cs, r.get_approved_term()) def update_lease_wrapper(self, reservation: ReservationClient, rtype: ResourceType, units: int, cs: ABCConcreteSet, term: Term): if reservation.state == ReservationStates.Ticketed: reservation.leased_resources = reservation.resources.abstract_clone( ) reservation.leased_resources.units = units reservation.leased_resources.type = rtype reservation.leased_resources.set_resources(cset=cs) reservation.previous_lease_term = None reservation.previous_term = reservation.term reservation.lease_term = term.clone() reservation.term = reservation.lease_term reservation.transition(prefix="redeem", state=ReservationStates.Active, pending=ReservationPendingStates.None_) else: reservation.leased_resources.units = units reservation.leased_resources.type = rtype reservation.leased_resources.resources.change(concrete_set=cs, configure=False) reservation.previous_lease_term = reservation.requested_term reservation.previous_term = reservation.term reservation.lease_term = term.clone() reservation.term = reservation.lease_term reservation.transition(prefix="redeem", state=ReservationStates.Active, pending=ReservationPendingStates.None_) def update_ticket_wrapper(self, reservation: ReservationClient, rtype: ResourceType, units: int, ticket: Ticket, term: Term): if reservation.state == ReservationStates.Nascent: reservation.resources = reservation.get_approved_resources( ).abstract_clone() reservation.resources.units = units reservation.resources.type = rtype reservation.resources.set_resources(cset=ticket) reservation.previous_ticket_term = None reservation.previous_term = None reservation.term = term.clone() reservation.ticket_term = reservation.term reservation.transition(prefix="ticket", state=ReservationStates.Ticketed, pending=ReservationPendingStates.None_) else: reservation.resources.units = units reservation.resources.type = rtype reservation.resources.resources.change(concrete_set=ticket, configure=False) reservation.previous_term = reservation.term reservation.previous_ticket_term = reservation.ticket_term reservation.term = term.clone() reservation.ticket_term = reservation.term reservation.transition(prefix="extendticket", state=ReservationStates.ActiveTicketed, pending=ReservationPendingStates.None_) def fail_ticket(self, r: ReservationClient): r.transition(prefix="fail", state=ReservationStates.Failed, pending=ReservationPendingStates.None_)
class BaseTestCase: actor_name = "testActor" actor_guid = ID() authority_name = "Test-Authority" broker_name = "Test-Broker" controller_name = "Test-Controller" controller_guid = "test-orchestrator-guid" authority_guid = "test-authority-guid" broker_guid = "test-broker-guid" db_user = '******' db_pwd = 'fabric' db_name = 'test' db_host = '152.54.15.56:5432' logger = logging.getLogger('BaseTestCase') log_format = '%(asctime)s - %(name)s - {%(filename)s:%(lineno)d} - [%(threadName)s] - %(levelname)s - %(message)s' logging.basicConfig(format=log_format, filename="./actor.log") logger.setLevel(logging.INFO) Term.set_cycles = False def get_container_database(self) -> ABCContainerDatabase: from fabric_cf.actor.core.container.globals import GlobalsSingleton return GlobalsSingleton.get().get_container().get_database() def get_actor_clock(self) -> ActorClock: from fabric_cf.actor.core.container.globals import GlobalsSingleton return GlobalsSingleton.get().get_container().get_actor_clock() def make_actor_database(self) -> ABCDatabase: return ActorDatabase(user=self.db_user, password=self.db_pwd, database=self.db_name, db_host=self.db_host, logger=self.logger) def make_controller_database(self) -> ABCDatabase: return self.make_actor_database() def make_broker_database(self) -> ABCDatabase: return self.make_actor_database() def make_authority_database(self) -> ABCDatabase: return self.make_actor_database() def initialize_database(self, *, db: ActorDatabase, name: str): db.set_actor_name(name=name) db.initialize() def get_actor_database(self, *, name: str = None) -> ABCDatabase: if name is None: name = self.actor_name db = self.make_actor_database() self.initialize_database(db=db, name=name) return db def get_controller_database(self, *, name: str) -> ABCDatabase: db = self.make_controller_database() db.set_actor_name(name=name) db.initialize() return db def get_authority_database(self, *, name: str) -> ABCDatabase: db = self.make_authority_database() db.set_actor_name(name=name) db.initialize() return db def get_broker_database(self, *, name: str) -> ABCDatabase: db = self.make_broker_database() db.set_actor_name(name=name) db.initialize() return db def make_plugin(self) -> ABCBasePlugin: return BasePlugin(actor=None, db=None, handler_processor=None) def get_plugin(self, *, name: str = None) -> ABCBasePlugin: if name is None: name = self.actor_name plugin = self.make_plugin() plugin.set_database(db=self.get_actor_database(name=name)) return plugin def get_controller_plugin(self, *, name: str) -> ABCBasePlugin: plugin = self.make_plugin() plugin.set_database(db=self.get_controller_database(name=name)) return plugin def get_broker_plugin(self, *, name: str) -> ABCBasePlugin: plugin = self.make_plugin() plugin.set_database(db=self.get_broker_database(name=name)) return plugin def get_authority_plugin(self, *, name: str) -> ABCBasePlugin: plugin = self.make_plugin() plugin.set_database(db=self.get_authority_database(name=name)) return plugin def get_policy(self) -> ABCPolicy: return Policy() def get_authority_policy(self) -> ABCAuthorityPolicy: return AuthorityPolicy(actor=None) def get_broker_policy(self) -> ABCBrokerPolicyMixin: return BrokerPolicy(actor=None) def get_controller_policy(self) -> ABCControllerPolicy: return ControllerTicketReviewPolicy() def get_actor_instance(self) -> ABCActorMixin: from fabric_cf.actor.test.test_actor import TestActor actor = TestActor() actor.type = ActorType.All return actor def get_authority_instance(self) -> ABCActorMixin: from fabric_cf.actor.core.core.authority import Authority return Authority() def get_broker_instance(self) -> ABCActorMixin: from fabric_cf.actor.core.core.broker import Broker return Broker() def get_controller_instance(self) -> ABCActorMixin: from fabric_cf.actor.core.core.controller import Controller return Controller() def get_uninitialized_actor(self, *, name: str, guid: ID) -> ABCActorMixin: actor = self.get_actor_instance() token = AuthToken(name=name, guid=guid) actor.set_identity(token=token) actor.set_actor_clock(clock=self.get_actor_clock()) actor.set_policy(policy=self.get_policy()) actor.set_plugin(plugin=self.get_plugin(name=name)) return actor def get_uninitialized_controller(self, *, name: str, guid: ID) -> ABCController: actor = self.get_controller_instance() token = AuthToken(name=name, guid=guid) actor.set_identity(token=token) actor.set_actor_clock(clock=self.get_actor_clock()) actor.set_policy(policy=self.get_controller_policy()) actor.set_plugin(plugin=self.get_plugin(name=name)) return actor def get_uninitialized_broker(self, *, name: str, guid: ID) -> ABCBrokerMixin: actor = self.get_broker_instance() token = AuthToken(name=name, guid=guid) actor.set_identity(token=token) actor.set_actor_clock(clock=self.get_actor_clock()) actor.set_policy(policy=self.get_broker_policy()) actor.set_plugin(plugin=self.get_plugin(name=name)) return actor def get_uninitialized_authority(self, *, name: str, guid: ID) -> ABCAuthority: actor = self.get_authority_instance() token = AuthToken(name=name, guid=guid) actor.set_identity(token=token) actor.set_actor_clock(clock=self.get_actor_clock()) actor.set_policy(policy=self.get_authority_policy()) actor.set_plugin(plugin=self.get_plugin(name=name)) return actor def get_actor(self, *, name: str = actor_name, guid: ID = actor_guid) -> ABCActorMixin: actor = self.get_uninitialized_actor(name=name, guid=guid) actor.initialize() self.register_new_actor(actor=actor) return actor def get_controller(self, *, name: str = controller_name, guid: ID = controller_guid) -> ABCController: actor = self.get_uninitialized_controller(name=name, guid=guid) actor.initialize() self.register_new_actor(actor=actor) return actor def get_broker(self, *, name: str = broker_name, guid: ID = broker_guid) -> ABCBrokerMixin: actor = self.get_uninitialized_broker(name=name, guid=guid) actor.initialize() self.register_new_actor(actor=actor) return actor def get_authority(self, *, name: str = authority_name, guid: ID = authority_guid) -> ABCAuthority: actor = self.get_uninitialized_authority(name=name, guid=guid) actor.initialize() self.register_new_actor(actor=actor) return actor def register_new_actor(self, *, actor: ABCActorMixin): db = self.get_container_database() db.remove_actor(actor_name=actor.get_name()) db.add_actor(actor=actor) ActorRegistrySingleton.get().unregister(actor=actor) ActorRegistrySingleton.get().register_actor(actor=actor) actor.actor_added() actor.start() def get_registered_new_actor(self) -> ABCActorMixin: actor = self.get_actor() self.register_new_actor(actor=actor) return actor