Skip to content

Commit

Permalink
consolidated some resources, implemented cross-origin handling, fixed…
Browse files Browse the repository at this point in the history
… some bugs in service layer
  • Loading branch information
mguenther committed Oct 10, 2015
1 parent 5c83a75 commit 6979d1f
Show file tree
Hide file tree
Showing 26 changed files with 471 additions and 131 deletions.
51 changes: 51 additions & 0 deletions photoalbum-bootstrap/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,57 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mgu.photoalbum.bootstrap.Bootstrap</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.mgu.photoalbum</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,8 @@ public void untag() {
public static PhotoBuilder create() {
return new PhotoBuilder();
}

public boolean anyTagMatches(final List<String> tags) {
return tags.isEmpty() || getTags().stream().anyMatch(tag -> tags.contains(tag));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ public interface AlbumCommandService {
String createAlbum(String ownerId, String title);

void deleteAlbum(String id);

void removePhotoFromAlbum(String albumId, String photoId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import com.mgu.photoalbum.domain.Album;
import com.mgu.photoalbum.identity.IdGenerator;
import com.mgu.photoalbum.storage.AlbumRepository;
import org.ektorp.UpdateConflictException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

Expand Down Expand Up @@ -54,6 +57,20 @@ public void deleteAlbum(final String id) {
repository.remove(album);
}

@Override
public void removePhotoFromAlbum(String albumId, String photoId) {
if (!repository.contains(albumId)) {
return;
}
final Album album = repository.get(albumId);
album.dissociatePhoto(photoId);
try {
repository.update(album);
} catch (UpdateConflictException e) {
throw new UnableToUpdateAlbumException(albumId, e);
}
}

@Override
public Album albumById(final String id) {
if (!repository.contains(id)) {
Expand All @@ -64,7 +81,9 @@ public Album albumById(final String id) {
}

@Override
public List<Album> albumsByOwner(String ownerId) {
return null;
public List<Album> albumsByOwner(final String ownerId) {
final List<Album> albumsByOwner = new ArrayList<>();
albumsByOwner.addAll(repository.getAllByOwner(ownerId));
return Collections.unmodifiableList(albumsByOwner);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@

public interface PhotoQueryService {

byte[] originalById(String id); // byte[] originalById(PhotoId identity)
byte[] originalById(String id);

byte[] thumbnailById(String id);

Photo photoById(String id);

List<Photo> photosByAlbumAndTags(String albumId, List<String> tags);

List<Photo> search(String albumId, List<String> tags, int offset, int pageSize);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import java.nio.file.Path;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class PhotoService implements PhotoCommandService, PhotoQueryService {

private static final Logger LOGGER = LoggerFactory.getLogger(PhotoService.class);

private final PhotoRepository repository;

private final AlbumCommandService albumCommandService;

private final PathScheme pathScheme;

private final PathAdapter pathAdapter;
Expand All @@ -35,18 +38,20 @@ public class PhotoService implements PhotoCommandService, PhotoQueryService {

@Inject
public PhotoService(
final AlbumCommandService albumCommandService,
final PhotoRepository repository,
final PathScheme pathScheme,
final PathAdapter pathAdapter,
final InputStreamAdapter inputStreamAdapter,
final IdGenerator idGenerator,
final ImageScaler scaler) {
this.repository = repository;
this.albumCommandService = albumCommandService;
this.pathAdapter = pathAdapter;
this.inputStreamAdapter = inputStreamAdapter;
this.pathScheme = pathScheme;
this.scaler = scaler;
this.photoIdGenerator = () -> idGenerator.generateId("AL", 14);
this.photoIdGenerator = () -> idGenerator.generateId("PH", 14);
}

@Override
Expand Down Expand Up @@ -100,6 +105,7 @@ public void deletePhoto(final String photoId) {
final Path photoFolder = pathScheme.constructPathToPhotoFolder(photo.getOwnerId(), photo.getAlbumId(), photoId);
pathAdapter.deleteDirectory(photoFolder);
repository.remove(photo);
albumCommandService.removePhotoFromAlbum(photo.getAlbumId(), photoId);
}

@Override
Expand All @@ -114,7 +120,7 @@ public void updateMetadata(final String photoId, final String description, final
try {
repository.update(photo);
} catch (UpdateConflictException e) {
throw new UnableToUpdateMetadata(photoId, description, tags);
throw new UnableToUpdateMetadataException(photoId, description, tags);
}
}

Expand Down Expand Up @@ -160,13 +166,14 @@ public Photo photoById(final String photoId) {
return repository.get(photoId);
}

@Override
public List<Photo> photosByAlbumAndTags(final String albumId, final List<String> tags) {
return null;
}

@Override
public List<Photo> search(final String albumId, final List<String> tags, final int offset, final int pageSize) {
return null;
return repository
.getAllByAlbum(albumId)
.stream()
.filter(photo -> photo.anyTagMatches(tags))
.skip(offset)
.limit(pageSize)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mgu.photoalbum.service;

import com.mgu.photoalbum.exception.PhotoalbumException;

public class UnableToUpdateAlbumException extends PhotoalbumException {

private static final String ERROR_MESSAGE = "Unable to update the album with ID %s.";

public UnableToUpdateAlbumException(final String albumId, final Throwable t) {
super(String.format(ERROR_MESSAGE, albumId));
}

@Override
public String getErrorCode() {
return "P005";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

import java.util.List;

public class UnableToUpdateMetadata extends PhotoalbumException {
public class UnableToUpdateMetadataException extends PhotoalbumException {

private static final String ERROR_MESSAGE = "Unable to set description to %s and replace existing tags by %s for photo with ID %s.";

public UnableToUpdateMetadata(final String photoId, final String description, final List<String> tags) {
public UnableToUpdateMetadataException(final String photoId, final String description, final List<String> tags) {
super(String.format(ERROR_MESSAGE, description, StringUtils.join(tags, ","), photoId));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@
import com.mgu.photoalbum.adapter.couchdb.DocumentRepository;
import com.mgu.photoalbum.domain.Album;
import org.ektorp.CouchDbConnector;
import org.ektorp.ViewQuery;
import org.ektorp.support.View;
import org.ektorp.support.Views;

import java.util.List;

@Views({
@View(name = "all", map = "function(doc) { if (doc.type == '" + Album.DOCUMENT_TYPE + "') emit(null, doc._id)}"),
@View(name = "by_owner", map = "function(doc) { if ('type' in doc && doc.type === 'album') { if ('ownerId' in doc) { emit(doc.ownerId, doc); } } }")
})
public class AlbumRepository extends DocumentRepository<Album> {

@Inject
public AlbumRepository(final CouchDbConnector connector) {
super(Album.class, connector);
initStandardDesignDocument();
}

public List<Album> getAllByOwner(final String ownerId) {
final ViewQuery query = new ViewQuery()
.designDocId("_design/Album")
.viewName("by_owner")
.includeDocs(true)
.key(ownerId);
return connector.queryView(query, Album.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@
import com.mgu.photoalbum.adapter.couchdb.DocumentRepository;
import com.mgu.photoalbum.domain.Photo;
import org.ektorp.CouchDbConnector;
import org.ektorp.ViewQuery;
import org.ektorp.support.View;
import org.ektorp.support.Views;

import java.util.List;

@Views({
@View(name = "all", map = "function(doc) { if (doc.type == '" + Photo.DOCUMENT_TYPE + "') emit(null, doc._id)}"),
@View(name = "by_album", map = "function(doc) { if ('type' in doc && doc.type === 'photo') { if ('albumId' in doc) { emit(doc.albumId, doc); } } }")
})
public class PhotoRepository extends DocumentRepository<Photo> {

@Inject
public PhotoRepository(final CouchDbConnector connector) {
super(Photo.class, connector);
initStandardDesignDocument();
}

public List<Photo> getAllByAlbum(final String albumId) {
final ViewQuery query = new ViewQuery()
.designDocId("_design/Photo")
.viewName("by_album")
.includeDocs(true)
.key(albumId);
return connector.queryView(query, Photo.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mgu.photoalbum;

import com.hubspot.dropwizard.guice.GuiceBundle;
import com.mgu.photoalbum.config.CrossOriginConfig;
import com.mgu.photoalbum.config.ServiceConfig;
import com.mgu.photoalbum.config.ServiceModule;
import com.mgu.photoalbum.security.Principal;
Expand All @@ -9,6 +10,11 @@
import io.dropwizard.auth.basic.BasicAuthFactory;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.eclipse.jetty.servlets.CrossOriginFilter;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import java.util.EnumSet;

public class PhotoalbumApplication extends Application<ServiceConfig> {

Expand All @@ -35,6 +41,16 @@ public void run(final ServiceConfig serviceConfig, final Environment environment
environment
.jersey()
.register(AuthFactory.binder(new BasicAuthFactory<>(authenticator, "Photoalbum Realm", Principal.class)));

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORSFilter", CrossOriginFilter.class);

filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, environment.getApplicationContext().getContextPath() + "*");
filter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
filter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
filter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Origin, Content-Type, Accept, Authorization");
filter.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
}

@Override
Expand Down

0 comments on commit 6979d1f

Please sign in to comment.