def get_feature_type_elements_xml(title, service_type_version, service_type, uri, external_auth): """ Requests a DescribeFeatureType document Args: title (str): service_type_version (str): service_type (str): uri (str): external_auth (ExternalAuthentication): Returns: None | str """ from service.helper.common_connector import CommonConnector connector = CommonConnector(url=uri, external_auth=external_auth) type_name = "typeName" if service_type_version == OGCServiceVersionEnum.V_2_0_0 or service_type_version == OGCServiceVersionEnum.V_2_0_2: type_name = "typeNames" params = { "service": service_type, "version": service_type_version, "request": "DescribeFeatureType", type_name: title } try: connector.load(params=params) response = connector.content response = parse_xml(response) except ConnectionError: return None except ProxyError: return None return response
def get_category_json(self, category_url, language): """ Loads the json response from a connector class Args: category_url: The uri where the definitions can be loaded from language: The language which shall be fetched Returns: response (str): The response body content """ uri_lang = category_url.format(language) if (CommonConnector().url_is_reachable("https://www.google.de/", 10)[0] is not True): self.stdout.write( self.style.NOTICE( "Internet connection test failed! Proxies have to be specified in MrMap/settings.py." )) self.stdout.write( self.style.NOTICE( "Setup will be canceled! Please make sure to have a working internet connection!" )) exit() connector = CommonConnector(uri_lang) connector.load() return connector.content
def check_status(self, url: str, check_wfs_member: bool = False, check_image: bool = False) -> ServiceStatus: """ Check status of ogc service. Args: url (str): URL to the service that should be checked. check_wfs_member (bool): True, if a returned xml should check for a 'member' tag. check_image (bool): True, if the returned content should be checked as image. Returns: ServiceStatus: Status info of service. """ success = False duration = None connector = CommonConnector(url=url, timeout=self.monitoring_settings.timeout if self.monitoring_settings is not None else MONITORING_REQUEST_TIMEOUT) if self.metadata.has_external_authentication: connector.external_auth = self.metadata.external_authentication try: connector.load() except Exception as e: # handler if server sends no response (e.g. outdated uri) response_text = str(e) return Monitoring.ServiceStatus(url, success, response_text, connector.status_code, duration) duration = timezone.timedelta(seconds=connector.run_time) response_text = connector.content if connector.status_code == 200: success = True try: xml = parse_xml(response_text) if 'Exception' in xml.getroot().tag: success = False if check_wfs_member: if not self.has_wfs_member(xml): success = False except AttributeError: # handle successful responses that do not return xml response_text = None if check_image: try: Image.open(BytesIO(connector.content)) success = True except UnidentifiedImageError: success = False service_status = Monitoring.ServiceStatus(url, success, response_text, connector.status_code, duration) return service_status
def fetch_validation_document(self): """ Fetches the XML document that is to be validated. Returns: str: document to be validated """ validation_target = self.config.validation_target doc_url = getattr(self.metadata, validation_target) quality_logger.info( f"Retrieving document for validation from {doc_url}") connector = CommonConnector(url=doc_url) connector.load() if connector.status_code != requests.codes.ok: raise Exception( f"Unexpected HTTP response code {connector.status_code} when " f"retrieving document from: {doc_url}") return connector.content
def get_metadata_legend(request: HttpRequest, metadata_id, style_id: int): """ Calls the legend uri of a special style inside the metadata (<LegendURL> element) and returns the response to the user This function has to be public available (no check_session decorator) Args: request (HttpRequest): The incoming HttpRequest metadata_id: The metadata id style_id (int): The style id Returns: HttpResponse """ style = get_object_or_404(Style, id=style_id) uri = style.legend_uri con = CommonConnector(uri) con.load() response = con.content return HttpResponse(response, content_type="")
def get_capabilities(self): """ Start a network call to retrieve the original capabilities xml document. Using the connector class, this function will GET the capabilities xml document as string. No file will be downloaded and stored on the storage. The string will be stored in the OGCWebService instance. Returns: nothing """ params = { "request": OGCOperationEnum.GET_CAPABILITIES.value, "version": self.service_version.value if self.service_version is not None else "", "service": (self.service_type.value if self.service_type is not None else "").upper(), } concat = "&" if self.service_connect_url[-1] != "&" else "" self.service_connect_url = "{}{}{}".format(self.service_connect_url, concat, urlencode(params)) ows_connector = CommonConnector( url=self.service_connect_url, external_auth=self.external_authentification, connection_type=ConnectionEnum.REQUESTS) ows_connector.http_method = 'GET' try: ows_connector.load() if ows_connector.status_code != 200: raise ConnectionError(ows_connector.status_code) except ReadTimeout: raise ConnectionError( CONNECTION_TIMEOUT.format(self.service_connect_url)) tmp = ows_connector.content.decode("UTF-8") # check if tmp really contains an xml file xml = xml_helper.parse_xml(tmp) if xml is None: raise Exception(tmp) self.service_capabilities_xml = tmp self.connect_duration = ows_connector.run_time self.descriptive_document_encoding = ows_connector.encoding
def get_metadata(self): """ Start a network call to retrieve the original capabilities xml document. Using the connector class, this function will GET the capabilities xml document as string. No file will be downloaded and stored on the storage. The string will be stored in the OGCWebService instance. Returns: nothing """ ows_connector = CommonConnector( url=self.uri, external_auth=None, connection_type=ConnectionEnum.REQUESTS) ows_connector.http_method = 'GET' ows_connector.load() if ows_connector.status_code != 200: raise ConnectionError(ows_connector.status_code) self.raw_metadata = ows_connector.content.decode("UTF-8")
def _get_harvest_response(self, result_type: str = "results") -> (bytes, int): """ Fetch a response for the harvesting (GetRecords) Args: result_type (str): Which resultType should be used (hits|results) Returns: harvest_response (bytes): The response content status_code (int): The response status code """ from service.helper.common_connector import CommonConnector connector = CommonConnector(url=self.harvest_url) if self.method.upper() == "GET": params = { "service": "CSW", "typeNames": "gmd:MD_Metadata", "resultType": result_type, "startPosition": self.start_position, "outputFormat": self.output_format, "maxRecords": self.max_records_per_request, "version": self.version, "request": OGCOperationEnum.GET_RECORDS.value, "outputSchema": HARVEST_GET_REQUEST_OUTPUT_SCHEMA, } connector.load(params=params) harvest_response = connector.content elif self.method.upper() == "POST": post_body = self._generate_request_POST_body( self.start_position, result_type=result_type) connector.post(data=post_body) harvest_response = connector.content else: raise NotImplementedError() return harvest_response, connector.status_code
def check_uri_provides_ogc_capabilities(value) -> ValidationError: """ Checks whether a proper XML OGC Capabilities document can be found at the given url. Args: value: The url parameter Returns: None|ValidationError: None if the checks are valid, ValidationError else """ connector = CommonConnector(url=value) connector.load() if connector.status_code == 401: # This means the resource needs authentication to be called. At this point we can not check whether this is # a proper OGC capabilities or not. Skip this check. return None try: xml_response = xml_helper.parse_xml(connector.content) root_elem = xml_response.getroot() tag_text = root_elem.tag if "Capabilities" not in tag_text: return ValidationError(_("This is no capabilities document.")) except AttributeError: # No xml found! return ValidationError(_("No XML found."))
def check_uri_is_reachable(value) -> (bool, bool, int): """ Performs a check on the URL. Returns whether it's reachable or not Args: value: The url to be checked Returns: reachable (bool) needs_authentication (bool) status_code (int) """ connector = CommonConnector(url=value) is_reachable, status_code = connector.url_is_reachable() if not is_reachable: if status_code < 0: # Not even callable! msg_suffix = "URL could not be resolved to a server. Please check your input!" else: msg_suffix = "Status code was {}".format(status_code) return ValidationError(message="URL not valid! {}".format(msg_suffix)) needs_authentication = status_code == 401 return is_reachable, needs_authentication, status_code
def capabilities_are_different(cap_url_1, cap_url_2): """ Loads two capabilities documents using uris and checks if they differ Args: cap_url_1: First capabilities url cap_url_2: Second capabilities url Returns: bool: True if they differ, false if they are equal """ # load xmls connector = CommonConnector(cap_url_1) connector.load() xml_1 = connector.content connector = CommonConnector(cap_url_2) connector.load() xml_2 = connector.content sec_handler = CryptoHandler() # hash both and compare hashes xml_1_hash = sec_handler.sha256(xml_1) xml_2_hash = sec_handler.sha256(xml_2) return xml_1_hash != xml_2_hash
def test_new_service_check_capabilities_uri(self): return """ Tests whether capabilities uris for the service and layers are set. Performs a retrieve check: Connects to the given uri and checks if the received xml matches with the persisted capabilities document. Checks for the service. Checks for each layer. Returns: """ service = self.service_wms layers = service.get_subelements() cap_doc = self.cap_doc_wms.content cap_uri = service.metadata.capabilities_original_uri connector = CommonConnector(url=cap_uri) connector.load() # Only check if the uri is valid and can be used to receive some data self.assertEqual( connector.status_code, 200, msg="URL '{}' didn't respond with status code 200".format(cap_uri)) for layer in layers: cap_uri_layer = layer.metadata.capabilities_original_uri if cap_uri == cap_uri_layer: # we assume that the same uri in a layer will receive the same xml document. ONLY if the uri would be different # we run another check. We can be sure that this check will fail, since a capabilities document # should only be available using a unique uri - but you never know... continue connector = CommonConnector(url=cap_uri) self.assertEqual( connector.status_code, 200, msg="URL '{}' didn't respond with status code 200".format( cap_uri))