@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public UGC update( @SecuredObject final String ugcId, final String body, final String subject, final String contextId, final Map attributes) throws SocialException, UGCNotFound { log.debug("logging.ugc.updateUgc", ugcId); try { final Profile currentProfile = SocialSecurityUtils.getCurrentProfile(); boolean moderateByMail = Boolean.parseBoolean( tenantConfigurationService.getProperty(contextId, "moderateByMailEnable").toString()); if (!ObjectId.isValid(ugcId)) { throw new IllegalArgumentException("Given UGC Id is not valid"); } T toUpdate = (T) ugcRepository.findUGC(contextId, ugcId); if (toUpdate == null) { throw new IllegalArgumentException("UGC with Id " + ugcId + " does not exists"); } if (StringUtils.isNotBlank(body)) { toUpdate.setBody(body); } if (StringUtils.isNotBlank(subject)) { toUpdate.setBody(subject); } pipeline.processUgc(toUpdate); if (moderateByMail && !SocialSecurityUtils.isProfileModeratorOrAdmin(currentProfile, contextId)) { if (toUpdate instanceof SocialUgc) { ((SocialUgc) toUpdate).setModerationStatus(ModerationStatus.UNMODERATED); } } ugcRepository.update(ugcId, toUpdate, false, false); final SocialEvent<T> event = new SocialEvent<>( toUpdate, SocialSecurityUtils.getCurrentProfile().getId().toString(), UGCEvent.UPDATE); event.setAttribute("baseUrl", calculateBaseUrl()); reactor.notify(UGCEvent.UPDATE.getName(), Event.wrap(event)); if (attributes != null && !attributes.isEmpty()) { toUpdate.getAttributes().putAll(attributes); // ToDo This should be one query, problem is with deep attributes !! setAttributes(toUpdate.getId().toString(), contextId, toUpdate.getAttributes()); reactor.notify(UGCEvent.UPDATE_ATTRIBUTES, Event.wrap(attributes)); } log.info("logging.ugc.updatedUgc", ugcId); return toUpdate; } catch (MongoDataException ex) { log.error("logging.ugc.unableToUpdateUgc", ex); throw new UGCException("Unable to removeWatcher UGC", ex); } }
private void threadPoolDispatcher() { Boundary b = new Boundary(); // Bind to a Selector using an anonymous object Tuple2<Selector, Object> anon = $(); threadPoolReactor.on(anon.getT1(), b.bind(consumer, 3)); threadPoolReactor.notify(anon.getT2(), Event.wrap(threadPoolReactor)); threadPoolReactor.notify(anon.getT2(), Event.wrap(threadPoolReactor)); threadPoolReactor.notify(anon.getT2(), Event.wrap(threadPoolReactor)); b.await(); }
@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public FileInfo updateAttachment( @SecuredObject final String ugcId, final String contextId, final String attachmentId, final InputStream newAttachment) throws UGCException, FileNotFoundException { if (!ObjectId.isValid(ugcId)) { throw new IllegalArgumentException("Given Ugc Id is not valid"); } if (!ObjectId.isValid(attachmentId)) { throw new IllegalArgumentException("Given UGC Id is not valid"); } try { T ugc = (T) ugcRepository.findUGC(contextId, ugcId); if (ugc == null) { throw new IllegalUgcException("Given UGC Id does not exists"); } FileInfo oldInfo = ugcRepository.getFileInfo(attachmentId); ugc.getAttachments().remove(oldInfo); FileInfo newInfo = ugcRepository.updateFile( new ObjectId(attachmentId), newAttachment, oldInfo.getFileName(), oldInfo.getContentType(), true); ugc.getAttachments().add(newInfo); ugcRepository.update(ugcId, ugc); reactor.notify( UGCEvent.DELETE_ATTACHMENT.getName(), Event.wrap(new SocialEvent<>(ugcId, attachmentId, UGCEvent.DELETE_ATTACHMENT))); reactor.notify( UGCEvent.ADD_ATTACHMENT.getName(), Event.wrap( new SocialEvent<>( ugcId, new InputStream[] {new CloseShieldInputStream(newAttachment)}), UGCEvent.ADD_ATTACHMENT)); return newInfo; } catch (MongoDataException e) { log.error("logging.ugc.attachmentError"); throw new UGCException("Unable to removeWatcher Attachment"); } catch (FileExistsException e) { log.error("logging.ugc.attachmentNotFound", attachmentId); throw new UGCException("Unable to find attachment with given id", e); } }
@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public void removeAttachment( @SecuredObject final String ugcId, final String contextId, final String attachmentId) throws UGCException, FileNotFoundException { try { UGC ugc = ugcRepository.findUGC(contextId, ugcId); if (ugc == null) { throw new IllegalUgcException("UGC with given Id does not exist"); } if (!ObjectId.isValid(attachmentId)) { throw new IllegalArgumentException("Given Attachment id is not valid"); } ObjectId attachmentOid = new ObjectId(attachmentId); FileInfo info = ugcRepository.getFileInfo(attachmentOid); if (!info.getStoreName().startsWith(File.separator + contextId)) { throw new IllegalSocialQueryException( "Given Attachment does not belong to the given context"); } ugc.getAttachments().remove(info); ugcRepository.deleteFile(attachmentOid); ugcRepository.update(ugcId, ugc); reactor.notify( UGCEvent.DELETE_ATTACHMENT.getName(), Event.wrap(new SocialEvent<>(ugcId, attachmentId, UGCEvent.DELETE_ATTACHMENT))); } catch (MongoDataException e) { log.error("logging.ugc.attachmentToRemove", e, attachmentId); throw new UGCException("Unable to save File to UGC"); } }
@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public void setAttributes( @SecuredObject final String ugcId, final String contextId, final Map attributes) throws SocialException, UGCNotFound { log.debug("logging.ugc.addingAttributes", attributes, ugcId, contextId); try { T toUpdate = (T) ugcRepository.findUGC(contextId, ugcId); if (toUpdate == null) { throw new UGCNotFound("Unable to found ugc with id " + ugcId); } final Map attrs = toUpdate.getAttributes(); attrs.putAll(attrs); ugcRepository.setAttributes(ugcId, contextId, attrs); final SocialEvent<T> event = new SocialEvent<T>( ugcId, attributes, SocialSecurityUtils.getCurrentProfile().getId().toString(), UGCEvent.UPDATE_ATTRIBUTES); event.setAttribute("baseUrl", calculateBaseUrl()); reactor.notify(UGCEvent.UPDATE_ATTRIBUTES.getName(), Event.wrap(event)); } catch (MongoDataException ex) { log.debug("logging.ugc.unableToAddAttrs", ex, attributes, ugcId, contextId); throw new UGCException("Unable to add Attributes to UGC", ex); } }
public void publishJokes() throws InterruptedException { long start = System.currentTimeMillis(); AtomicInteger counter = new AtomicInteger(); for (int i = 0; i < numberOfJokes; i++) { reactor.notify("jokes", Event.wrap(counter.getAndIncrement())); } latch.await(); long elapsed = System.currentTimeMillis() - start; System.out.println("Elapsed time: " + elapsed + "ms"); System.out.println("Average time per joke: " + elapsed / numberOfJokes + "ms"); }
private void multipleRingBufferDispatchers() { Boundary b = new Boundary(); Reactor r1 = Reactors.reactor().env(env).dispatcher(Environment.RING_BUFFER).get(); Reactor r2 = Reactors.reactor().env(env).dispatcher(Environment.RING_BUFFER).get(); // Bind to a Selector using an anonymous object Tuple2<Selector, Object> anon = $(); r1.on(anon.getT1(), b.bind(consumer, 3)); r2.on(anon.getT1(), b.bind(consumer, 2)); r1.notify(anon.getT2(), Event.wrap(r1)); r1.notify(anon.getT2(), Event.wrap(r1)); r1.notify(anon.getT2(), Event.wrap(r1)); r2.notify(anon.getT2(), Event.wrap(r2)); r2.notify(anon.getT2(), Event.wrap(r2)); b.await(); }
@Override @HasPermission(action = UGC_DELETE, type = SocialPermission.class) public boolean deleteUgc(final String ugcId, final String contextId) throws SocialException { log.debug("logging.ugc.deleteUgc", ugcId); try { ugcRepository.deleteUgc(ugcId, contextId); final SocialEvent<T> event = new SocialEvent<T>( ugcId, SocialSecurityUtils.getCurrentProfile().getId().toString(), UGCEvent.DELETE); event.setAttribute("baseUrl", calculateBaseUrl()); reactor.notify(UGCEvent.DELETE.getName(), Event.wrap(event)); } catch (MongoDataException ex) { log.error("logging.ugc.deleteUgcError", ex, ugcId, contextId); throw new UGCException("Unable to delete UGC", ex); } return false; }
@Override @HasPermission(action = UGC_CREATE, type = SocialPermission.class) public UGC create( final String contextId, final String ugcParentId, final String targetId, final String textContent, final String subject, final Map attrs, final boolean isAnonymous) throws SocialException { log.debug("logging.ugc.creatingUgc", contextId, targetId, ugcParentId, subject, attrs); final UGC template = new UGC(subject, textContent, targetId); template.setAnonymousFlag(isAnonymous); T newUgc = (T) ugcFactory.newInstance(template); newUgc.setAttributes(attrs); try { if (ObjectId.isValid(ugcParentId)) { setupAncestors(newUgc, ugcParentId, contextId); } else { log.debug("logging.ugc.invalidParentId"); } if (StringUtils.isBlank(contextId)) { throw new IllegalArgumentException("context cannot be null"); } pipeline.processUgc(newUgc); ugcRepository.save(newUgc); final SocialEvent<T> event = new SocialEvent<>( newUgc, SocialSecurityUtils.getCurrentProfile().getId().toString(), UGCEvent.CREATE); event.setAttribute("baseUrl", calculateBaseUrl()); reactor.notify(UGCEvent.CREATE.getName(), Event.wrap(event)); setupAutoWatch(targetId, SocialSecurityUtils.getCurrentProfile(), contextId); log.info("logging.ugc.created", newUgc); return newUgc; } catch (MongoDataException ex) { log.error("logging.ugc.errorSaving", ex); throw new UGCException("Unable to Save UGC"); } }
@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public FileInfo addAttachment( @SecuredObject final String ugcId, final String contextId, final InputStream attachment, final String fileName, final String contentType) throws FileExistsException, UGCException { String internalFileName = File.separator + contextId + File.separator + ugcId + File.separator + fileName; try { checkForVirus(attachment); } catch (IOException | VirusScannerException ex) { log.error("logging.ugc.errorScanVirus", ex); return null; } try { UGC ugc = ugcRepository.findUGC(contextId, ugcId); if (ugc == null) { throw new IllegalUgcException("UGC with given Id does not exist"); } FileInfo info = ugcRepository.saveFile(attachment, internalFileName, contentType); try { info.setFileName(new URLCodec().decode(fileName)); } catch (DecoderException e) { info.setFileName(fileName); } info.setAttribute("owner", ugcId); ugc.getAttachments().add(info); ugcRepository.update(ugcId, ugc); reactor.notify( UGCEvent.ADD_ATTACHMENT.getName(), Event.wrap( new SocialEvent<>( ugcId, new InputStream[] {new CloseShieldInputStream(attachment)}))); return info; } catch (MongoDataException e) { log.error("logging.ugc.unableToSaveAttachment", e, internalFileName); throw new UGCException("Unable to save File to UGC"); } }
@Override @HasPermission(action = UGC_UPDATE, type = SocialPermission.class) public void deleteAttribute( @SecuredObject final String ugcId, final String[] attributesName, final String contextId) throws SocialException { log.debug("logging.ugc.deleteAttributes", attributesName, ugcId); try { ugcRepository.deleteAttribute(ugcId, contextId, attributesName); final SocialEvent<T> event = new SocialEvent<T>( ugcId, SocialSecurityUtils.getCurrentProfile().getId().toString(), UGCEvent.DELETE_ATTRIBUTES); event.setAttribute("baseUrl", calculateBaseUrl()); reactor.notify(UGCEvent.DELETE_ATTRIBUTES.getName(), Event.wrap(event)); } catch (MongoDataException ex) { log.debug("logging.ugc.unableToDelAttrs", ex, attributesName, ugcId); throw new UGCException("Unable to delete attribute for ugc", ex); } }
public static void main(String[] args) throws InterruptedException { final TradeServer server = new TradeServer(); // Use a Reactor to dispatch events using the default Dispatcher Reactor reactor = new Reactor(); // Create a single Selector for efficiency Selector trade = $("trade.execute"); // For each Trade event, execute that on the server reactor.on( trade, new Consumer<Event<Trade>>() { @Override public void accept(Event<Trade> tradeEvent) { server.execute(tradeEvent.getData()); // Since we're async, for this test, use a latch to tell when we're done latch.countDown(); } }); // Start a throughput timer startTimer(); // Publish one event per trade for (int i = 0; i < totalTrades; i++) { // Pull next randomly-generated Trade from server Trade t = server.nextTrade(); // Notify the Reactor the event is ready to be handled reactor.notify(trade, Fn.event(t)); } // Stop throughput timer and output metrics endTimer(); server.stop(); }
/** * Notify this peer's consumers that the given channel has been closed. * * @param channel The channel that was closed. */ protected void notifyClose(@Nonnull NetChannel<IN, OUT> channel) { reactor.notify(close.getObject(), Event.wrap(channel)); }
/** * Notify this peer's consumers that the channel has been opened. * * @param channel The channel that was opened. */ protected void notifyOpen(@Nonnull NetChannel<IN, OUT> channel) { reactor.notify(open.getObject(), Event.wrap(channel)); }
/** * Notify this client's consumers than a global error has occurred. * * @param error The error to notify. */ protected void notifyError(@Nonnull Throwable error) { Assert.notNull(error, "Error cannot be null."); reactor.notify(error.getClass(), Event.wrap(error)); }
public static void main(String[] args) throws Exception { Environment env = new Environment(); final TradeServer server = new TradeServer(); // Use a Reactor to dispatch events using the high-speed Dispatcher final Reactor serverReactor = Reactors.reactor(env); // Create a single key and Selector for efficiency final Selector tradeExecute = Selectors.object("trade.execute"); // For each Trade event, execute that on the server and notify connected clients // because each client that connects links to the serverReactor serverReactor.on( tradeExecute, (Event<Trade> ev) -> { server.execute(ev.getData()); // Since we're async, for this test, use a latch to tell when we're done latch.countDown(); }); @SuppressWarnings("serial") WebSocketServlet wss = new WebSocketServlet() { @Override public void configure(WebSocketServletFactory factory) { factory.setCreator( (req, resp) -> new WebSocketListener() { AtomicLong counter = new AtomicLong(); @Override public void onWebSocketBinary(byte[] payload, int offset, int len) {} @Override public void onWebSocketClose(int statusCode, String reason) {} @Override public void onWebSocketConnect(final Session session) { LOG.info("Connected a websocket client: {}", session); // Keep track of a rolling average final AtomicReference<Float> avg = new AtomicReference<>(0f); serverReactor.on( tradeExecute, (Event<Trade> ev) -> { Trade t = ev.getData(); avg.set((avg.get() + t.getPrice()) / 2); // Send a message every 1000th trade. // Otherwise, we completely overwhelm the browser and network. if (counter.incrementAndGet() % 1000 == 0) { try { session .getRemote() .sendString(String.format("avg: %s", avg.get())); } catch (IOException e) { if (!"Failed to write bytes".equals(e.getMessage())) { e.printStackTrace(); } } } }); } @Override public void onWebSocketError(Throwable cause) {} @Override public void onWebSocketText(String message) {} }); } }; serve(wss); LOG.info( "Connect websocket clients now (waiting for 10 seconds).\n" + "Open websocket/src/main/webapp/ws.html in a browser..."); Thread.sleep(10000); // Start a throughput timer startTimer(); // Publish one event per trade for (int i = 0; i < totalTrades; i++) { // Pull next randomly-generated Trade from server Trade t = server.nextTrade(); // Notify the Reactor the event is ready to be handled serverReactor.notify(tradeExecute.getObject(), Event.wrap(t)); } // Stop throughput timer and output metrics endTimer(); server.stop(); }