Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] GeoNode signals/notification refactor #2911

Merged
merged 30 commits into from
Mar 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3a7b33b
notification refactor implementation
waybarrios Feb 15, 2017
8a7b9c7
Merge branch 'master' into pubsub
ingenieroariel Feb 22, 2017
d362038
Install geonode in docker
ingenieroariel Feb 22, 2017
6a12eb3
update settings for Docker use
waybarrios Feb 23, 2017
c5b9a84
Fix Travis error (log size was too big) and speed up test suite
ingenieroariel Feb 24, 2017
55f719d
Merge branch 'pubsub' of github.com:piensa/geonode into pubsub
ingenieroariel Feb 24, 2017
b8b2a75
Merge branch 'pubsub' of git://github.com/piensa/geonode into piensa-…
Feb 27, 2017
52520a5
Upgrade pavement to create notice types
ingenieroariel Feb 28, 2017
b8d5886
Added create_notices function for tests
ingenieroariel Feb 28, 2017
3e85594
Use create_notices on tests
ingenieroariel Feb 28, 2017
f2e25d0
Restrict incompatible versions of kombu
ingenieroariel Feb 28, 2017
fc02ca0
Added notifications to maps
ingenieroariel Mar 1, 2017
667e502
Added create_notifications to social tests and improved populate data…
ingenieroariel Mar 1, 2017
9be40c7
Disabled test that uncovers a recursive dependency
ingenieroariel Mar 1, 2017
7cf2624
Added tests placeholder for messaging
ingenieroariel Mar 1, 2017
0558611
Remove hardcoded wait
ingenieroariel Mar 6, 2017
8ad4ec7
Added oauth fixtures to integration tests
ingenieroariel Mar 6, 2017
48465bf
Added messaging to pavement.py
ingenieroariel Mar 6, 2017
d56b863
Move start_messaging after syncdb is done
ingenieroariel Mar 7, 2017
d522de8
Added manual geoserver post_save call to the integrtion tests
ingenieroariel Mar 9, 2017
e23d436
Merge branch 'pubsub' of git://github.com/piensa/geonode into piensa-…
Mar 9, 2017
acab55b
- Improve geoserver_post_save2 signals
Mar 9, 2017
955740a
- Improve geoserver_post_save2 signals
Mar 9, 2017
c4d7067
Merge branch 'pubsub' of github.com:piensa/geonode into pubsub
ingenieroariel Mar 9, 2017
f041fe2
pep8 for social/signals.py
ingenieroariel Mar 9, 2017
4209d82
pep8 security/views
ingenieroariel Mar 9, 2017
c277bc0
- pep8 fixes
Mar 9, 2017
8fc3e0a
pep8 fixes
ingenieroariel Mar 9, 2017
411c520
pep8
ingenieroariel Mar 9, 2017
abca5f7
Added integration tests to coverage
ingenieroariel Mar 10, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ slave

# virtual env
venv

celerybeat-*
manage.py

geonode/bin/
geonode/djcelery/
geonode/include/
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ MAINTAINER GeoNode development team
COPY requirements.txt /usr/src/app/
RUN pip install -r requirements.txt

RUN pip install .

EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ sync: up
docker-compose exec django django-admin.py loaddata sample_admin
docker-compose exec django django-admin.py loaddata geonode/base/fixtures/default_oauth_apps_docker.json
docker-compose exec django django-admin.py loaddata geonode/base/fixtures/initial_data.json
docker-compose exec django django-admin.py layer_notice_types

migrate:
django-admin.py migrate --noinput
Expand Down
24 changes: 12 additions & 12 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ Or if you want to use the provided Makefile::
**Note:**
For deveployment you need to add `geonode` alias into `/ect/hosts/` file as following:

```
$ sudo vim /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost geonode
255.255.255.255 broadcasthost
::1 localhost
```
$ sudo vim /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost geonode
255.255.255.255 broadcasthost
::1 localhost
To access GeoNode just enter the following url: `http://geonode/` on your web browser.
For GeoServer: `http://geonode/geoserver/web/`

Expand Down
10 changes: 10 additions & 0 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ services:
- '.:/usr/src/app'
environment:
- DEBUG=True

consumers:
build: .
# Loading the app is defined here to allow for
# autoreload on changes it is mounted on top of the
# old copy that docker added when creating the image
volumes:
- '.:/usr/src/app'
environment:
- DEBUG=True
13 changes: 12 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,22 @@ services:
command: celery worker --app=geonode.celery_app:app -B -l INFO
env_file:
- ./scripts/docker/env/production/django.env

consumers:
image: geonode/django
links:
- rabbitmq
- postgres
- elasticsearch
command: python manage.py runmessaging
env_file:
- ./scripts/docker/env/production/django.env

geoserver:
image: geonode/geoserver:alias
image: piensalabs/geoserver:pubsub
links:
- postgres
- rabbitmq
ports:
- "8080"
volumes_from:
Expand Down
2 changes: 1 addition & 1 deletion geonode/base/populate_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def create_models(type=None):
from django.contrib.auth.models import Group
map_data, user_data, people_data, layer_data, document_data = create_fixtures()
anonymous_group, created = Group.objects.get_or_create(name='anonymous')
u, _ = get_user_model().objects.get_or_create(username='admin', is_superuser=True, first_name='admin')
u, _ = get_user_model().objects.get_or_create(username='admin', defaults=dict(is_superuser=True, first_name='admin'))
u.set_password('admin')
u.save()
users = []
Expand Down
16 changes: 1 addition & 15 deletions geonode/catalogue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,7 @@ def catalogue_post_save(instance, sender, **kwargs):


def catalogue_pre_save(instance, sender, **kwargs):
"""Send information to catalogue"""
record = None

# if the layer is in the catalogue, try to get the distribution urls
# that cannot be precalculated.
try:
catalogue = get_catalogue()
record = catalogue.get_record(instance.uuid)
except EnvironmentError, err:
msg = 'Could not connect to catalogue to save information for layer "%s"' % instance.name
LOGGER.warn(msg, err)
raise err

if record is None:
return
pass


if 'geonode.catalogue' in settings.INSTALLED_APPS:
Expand Down
8 changes: 4 additions & 4 deletions geonode/documents/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from geonode.base.populate_test_data import create_models


class LayersTest(TestCase):
class DocumentsTest(TestCase):
fixtures = ['initial_data.json', 'bobby']

perm_spec = {
Expand All @@ -68,7 +68,7 @@ def test_create_document_with_no_rel(self):
self.imgfile.read(),
'image/gif')

superuser = get_user_model().objects.get(pk=2)
superuser = get_user_model().objects.filter(is_superuser=True)[0]
c = Document.objects.create(
doc_file=f,
owner=superuser,
Expand All @@ -83,7 +83,7 @@ def test_create_document_with_rel(self):
self.imgfile.read(),
'image/gif')

superuser = get_user_model().objects.get(pk=2)
superuser = get_user_model().objects.filter(is_superuser=True)[0]

m = Map.objects.all()[0]
ctype = ContentType.objects.get_for_model(m)
Expand All @@ -100,7 +100,7 @@ def test_create_document_with_rel(self):
def test_create_document_url(self):
"""Tests creating an external document instead of a file."""

superuser = get_user_model().objects.get(pk=2)
superuser = get_user_model().objects.filter(is_superuser=True)[0]
c = Document.objects.create(doc_url="http://geonode.org/map.pdf",
owner=superuser,
title="GeoNode Map",
Expand Down
90 changes: 60 additions & 30 deletions geonode/geoserver/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from django.utils.translation import ugettext
from django.conf import settings
from django.forms.models import model_to_dict

from geonode.geoserver.ows import wcs_links, wfs_links, wms_links
from geonode.geoserver.helpers import cascading_delete, set_attributes_from_geoserver
Expand All @@ -37,12 +38,19 @@
from geonode.base.models import ResourceBase
from geonode.base.models import Link
from geonode.people.models import Profile

from geoserver.layer import Layer as GsLayer
from geonode.social.signals import json_serializer_producer

logger = logging.getLogger("geonode.geoserver.signals")


def geoserver_delete(typename):
# cascading_delete should only be called if
# ogc_server_settings.BACKEND_WRITE_ENABLED == True
if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
cascading_delete(gs_catalog, typename)


def geoserver_pre_delete(instance, sender, **kwargs):
"""Removes the layer from GeoServer
"""
Expand All @@ -55,26 +63,51 @@ def geoserver_pre_delete(instance, sender, **kwargs):


def geoserver_pre_save(instance, sender, **kwargs):
"""Send information to geoserver.
"""
move the content of this task to post save signal
:param instance:
:param sender:
:param kwargs:
:return:
"""
pass

The attributes sent include:

* Title
* Abstract
* Name
* Keywords
* Metadata Links,
* Point of Contact name and url
def geoserver_post_save(instance, sender, **kwargs):
from geonode.messaging import producer
instance_dict = model_to_dict(instance)
payload = json_serializer_producer(instance_dict)
producer.geoserver_upload_layer(payload)


def geoserver_post_save2(layer_id):
"""Save keywords to GeoServer

The way keywords are implemented requires the layer
to be saved to the database before accessing them.
"""
"""Send information to geoserver.

The attributes sent include:

* Title
* Abstract
* Name
* Keywords
* Metadata Links,
* Point of Contact name and url
"""

from geonode.layers.models import Layer
instance = Layer.objects.get(id=layer_id)
# Don't run this signal if is a Layer from a remote service
if getattr(instance, "service", None) is not None:
return
return instance

# Don't run this signal handler if it is a tile layer
# Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
if hasattr(instance, 'storeType') and getattr(instance, 'storeType') == 'tileStore':
return
return instance

gs_resource = None

Expand All @@ -85,7 +118,8 @@ def geoserver_pre_save(instance, sender, **kwargs):

# There is no need to process it if there is not file.
if base_file is None:
return
return instance

gs_name, workspace, values, gs_resource = geoserver_upload(instance,
base_file.file.path,
instance.owner,
Expand All @@ -95,13 +129,17 @@ def geoserver_pre_save(instance, sender, **kwargs):
abstract=instance.abstract,
# keywords=instance.keywords,
charset=instance.charset)

# Set fields obtained via the geoserver upload.
instance.name = gs_name
instance.workspace = workspace
instance.store = values['store']
# Iterate over values from geoserver.
for key in ['typename', 'store', 'storeType']:
setattr(instance, key, values[key])

instance.save()

if not gs_resource:
gs_resource = gs_catalog.get_resource(
instance.name,
Expand All @@ -122,7 +160,8 @@ def geoserver_pre_save(instance, sender, **kwargs):
gs_resource.metadata_links = metadata_links
# gs_resource should only be called if
# ogc_server_settings.BACKEND_WRITE_ENABLED == True
if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED",
True):
gs_catalog.save(gs_resource)

gs_layer = gs_catalog.get_layer(instance.name)
Expand All @@ -137,7 +176,7 @@ def geoserver_pre_save(instance, sender, **kwargs):
'type': None}
profile = Profile.objects.get(username=instance.poc.username)
gs_layer.attribution_link = settings.SITEURL[
:-1] + profile.get_absolute_url()
:-1] + profile.get_absolute_url()
# gs_layer should only be called if
# ogc_server_settings.BACKEND_WRITE_ENABLED == True
if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
Expand All @@ -160,7 +199,7 @@ def geoserver_pre_save(instance, sender, **kwargs):
# self.srid = gs_resource.src

instance.srid_url = "http://www.spatialreference.org/ref/" + \
instance.srid.replace(':', '/').lower() + "/"
instance.srid.replace(':', '/').lower() + "/"

# Set bounding box values
instance.bbox_x0 = bbox[0]
Expand All @@ -171,28 +210,18 @@ def geoserver_pre_save(instance, sender, **kwargs):
# store the resource to avoid another geoserver call in the post_save
instance.gs_resource = gs_resource


def geoserver_post_save(instance, sender, **kwargs):
"""Save keywords to GeoServer

The way keywords are implemented requires the layer
to be saved to the database before accessing them.
"""
# Don't run this signal handler if it is a tile layer
# Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
if hasattr(instance, 'storeType') and getattr(instance, 'storeType') == 'tileStore':
return
instance.save()

if type(instance) is ResourceBase:
if hasattr(instance, 'layer'):
instance = instance.layer
else:
return
return instance

if instance.storeType == "remoteStore":
# Save layer attributes
set_attributes_from_geoserver(instance)
return
return instance

if not getattr(instance, 'gs_resource', None):
try:
Expand All @@ -205,12 +234,12 @@ def geoserver_post_save(instance, sender, **kwargs):
# Not the error we are looking for, re-raise
raise serr
# If the connection is refused, take it easy.
return
return instance
else:
gs_resource = instance.gs_resource

if gs_resource is None:
return
return instance

if settings.RESOURCE_PUBLISHING:
if instance.is_published != gs_resource.advertised:
Expand Down Expand Up @@ -469,6 +498,7 @@ def command_url(command):
from geonode.catalogue.models import catalogue_post_save
from geonode.layers.models import Layer
catalogue_post_save(instance, Layer)
return instance


def geoserver_pre_save_maplayer(instance, sender, **kwargs):
Expand Down
29 changes: 29 additions & 0 deletions geonode/layers/management/commands/layer_notice_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2016 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

from django.core.management.base import BaseCommand
from geonode.layers.populate_layers_data import create_notifications


class Command(BaseCommand):
help = ("Create notice types for layers")

def handle(self, *args, **options):
create_notifications()
Loading