This talk will cover how you can use Sencha's sencha.io cloud services in your Sencha Touch 2 mobile web app.
Sencha provides several service to create, store and share data in the cloud.
In this talk we go through the following services:
* Sencha.io Login: provides a set of APIs for user registration and login.
* Sencha.io Data: synchronizes data with the cloud.
* Sencha.io Messaging: enables reliable one-to-one and one-to-many messaging.
* Sencha.io Src: dynamically resize images for the ever increasing number of mobile screen sizes
and will see how to use and implement the services in detail.
The implementation will be explained by the code of an Sencha Touch 2 app using the sencha.io services.
Lesson_07_Spring_Security_Register_NEW.pdfScott Anderson
The document provides details about the code execution path for registering a new user on the Spring Security application at URL "http://localhost:8080/register".
When a user visits the registration page, the SecureAccessController handles the request and returns the registration view. If the user submits the registration form, the controller checks if the user already exists by calling the SecureAccessHandler, which queries the database. If the user does not exist, the handler registers the new user by saving it to the database using the UserRepository and SecureUserCredentialService, then the controller returns the login page. If the user does exist, an error is displayed on the registration page.
Creating a Facebook Clone - Part XXXVIII.pdfShaiAlmog1
The document discusses the implementation of posts, media, and comments for a Facebook clone application. Key points include:
- A Post entity supports one media file per post, comments, likes, and attachments through relationships to other entities.
- The PostDAO converts Post entities to plain Java objects for transferring data to and from the client.
- The PostService allows creating and sharing posts to friends' newsfeeds through repositories for posts, users, newsfeeds, comments, and media.
- The MediaService supports getting media attachments by ID, checking permissions and returning file data and metadata.
Angular 2 Component Communication - Talk by Rob McDiarmidAmrita Chopra
This talk was a part of the January 2017 AngularTO meetup at Rangle.io
All content is by Rob McDiarmid
Components are one of Angular 2's greatest features. They combine many redundant concepts from Angular 1.x into one flexible and elegant API. A Component can interact with its parent/children through @Input and @Output bindings but sometimes that's not enough. What happens when you need to communicate between siblings or nested routes? What if you need to send a message to multiple components at once or just need more control? Fortunately, Angular 2 has got you covered. Level up your component skills and learn some advanced features and patterns for component interaction.
Talk I gave at Maceió DEV Meetup #6. Not only about Command Bus/Command Interface or whatever you name it, but a compilation of cool articles I found only that may help with understanding this architecture.
Testando API's de forma unitária mocando as dependênciasMarcelo Aymone
Slides da talk na trilha de golang no TDC 2018.
Testando API's de forma unitária mocando as dependências aborda técnicas de mocks para testes unitários em golang.
There are so many interesting ways to authenticate a user: via an API token, social login, a traditional HTML form or anything else you can dream up. But until now, creating a custom authentication system in Symfony has meant a lot of files and a lot of complexity. Introducing Guard: a simple, but expandable authentication system built on top of the security component and introduced in Symfony 2.8. Want to authenticate via an API token? Great - that's just one class. Social login? Easy! Have some crazy legacy central authentication system? In this talk, we'll show you how you'd implement any of these in your application today. Don't get me wrong - you'll still need to do some work. But finally, the path will be clear and joyful.
Brief example how to use Free Monad in Scala (Cats lib). Also this presentation covers combination of two free monads.
Link to video: https://youtu.be/9-2uOyRec_I
The easy way to develop Java applications has always been the standard stack (Spring, JEE, SQL) that confirms the LAMP equivalent in Java-speak. This presentation compares this model with a real use case based on Guice, Jersey and AppEngine.
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
The document outlines an agenda for a workshop on debugging techniques. The workshop covers installing tools, flow and breakpoints debugging, watching variables, Kubernetes debugging, and developer observability. Key techniques discussed include tracepoints, memory debugging, exception breakpoints, object marking, and logs, snapshots, and metrics for observability. The goal is to teach practical debugging skills that can be applied at scale in production environments like Kubernetes.
This talk will cover how you can use Sencha's sencha.io cloud services in your Sencha Touch 2 mobile web app.
Sencha provides several service to create, store and share data in the cloud.
In this talk we go through the following services:
* Sencha.io Login: provides a set of APIs for user registration and login.
* Sencha.io Data: synchronizes data with the cloud.
* Sencha.io Messaging: enables reliable one-to-one and one-to-many messaging.
* Sencha.io Src: dynamically resize images for the ever increasing number of mobile screen sizes
and will see how to use and implement the services in detail.
The implementation will be explained by the code of an Sencha Touch 2 app using the sencha.io services.
Lesson_07_Spring_Security_Register_NEW.pdfScott Anderson
The document provides details about the code execution path for registering a new user on the Spring Security application at URL "http://localhost:8080/register".
When a user visits the registration page, the SecureAccessController handles the request and returns the registration view. If the user submits the registration form, the controller checks if the user already exists by calling the SecureAccessHandler, which queries the database. If the user does not exist, the handler registers the new user by saving it to the database using the UserRepository and SecureUserCredentialService, then the controller returns the login page. If the user does exist, an error is displayed on the registration page.
Creating a Facebook Clone - Part XXXVIII.pdfShaiAlmog1
The document discusses the implementation of posts, media, and comments for a Facebook clone application. Key points include:
- A Post entity supports one media file per post, comments, likes, and attachments through relationships to other entities.
- The PostDAO converts Post entities to plain Java objects for transferring data to and from the client.
- The PostService allows creating and sharing posts to friends' newsfeeds through repositories for posts, users, newsfeeds, comments, and media.
- The MediaService supports getting media attachments by ID, checking permissions and returning file data and metadata.
Angular 2 Component Communication - Talk by Rob McDiarmidAmrita Chopra
This talk was a part of the January 2017 AngularTO meetup at Rangle.io
All content is by Rob McDiarmid
Components are one of Angular 2's greatest features. They combine many redundant concepts from Angular 1.x into one flexible and elegant API. A Component can interact with its parent/children through @Input and @Output bindings but sometimes that's not enough. What happens when you need to communicate between siblings or nested routes? What if you need to send a message to multiple components at once or just need more control? Fortunately, Angular 2 has got you covered. Level up your component skills and learn some advanced features and patterns for component interaction.
Talk I gave at Maceió DEV Meetup #6. Not only about Command Bus/Command Interface or whatever you name it, but a compilation of cool articles I found only that may help with understanding this architecture.
Testando API's de forma unitária mocando as dependênciasMarcelo Aymone
Slides da talk na trilha de golang no TDC 2018.
Testando API's de forma unitária mocando as dependências aborda técnicas de mocks para testes unitários em golang.
There are so many interesting ways to authenticate a user: via an API token, social login, a traditional HTML form or anything else you can dream up. But until now, creating a custom authentication system in Symfony has meant a lot of files and a lot of complexity. Introducing Guard: a simple, but expandable authentication system built on top of the security component and introduced in Symfony 2.8. Want to authenticate via an API token? Great - that's just one class. Social login? Easy! Have some crazy legacy central authentication system? In this talk, we'll show you how you'd implement any of these in your application today. Don't get me wrong - you'll still need to do some work. But finally, the path will be clear and joyful.
Brief example how to use Free Monad in Scala (Cats lib). Also this presentation covers combination of two free monads.
Link to video: https://youtu.be/9-2uOyRec_I
The easy way to develop Java applications has always been the standard stack (Spring, JEE, SQL) that confirms the LAMP equivalent in Java-speak. This presentation compares this model with a real use case based on Guice, Jersey and AppEngine.
Similar to Creating a Facebook Clone - Part XXII - Transcript.pdf (18)
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
The document outlines an agenda for a workshop on debugging techniques. The workshop covers installing tools, flow and breakpoints debugging, watching variables, Kubernetes debugging, and developer observability. Key techniques discussed include tracepoints, memory debugging, exception breakpoints, object marking, and logs, snapshots, and metrics for observability. The goal is to teach practical debugging skills that can be applied at scale in production environments like Kubernetes.
The document describes code for implementing the server-side functionality of a WhatsApp clone. It includes classes for representing users, messages, and server connections. The Server class initializes user and message data from files, handles login/signup, and establishes a websocket connection for real-time messaging. It can send and receive messages when connected, or queue messages when offline.
A Comprehensive Guide to DeFi Development Services in 2024Intelisync
DeFi represents a paradigm shift in the financial industry. Instead of relying on traditional, centralized institutions like banks, DeFi leverages blockchain technology to create a decentralized network of financial services. This means that financial transactions can occur directly between parties, without intermediaries, using smart contracts on platforms like Ethereum.
In 2024, we are witnessing an explosion of new DeFi projects and protocols, each pushing the boundaries of what’s possible in finance.
In summary, DeFi in 2024 is not just a trend; it’s a revolution that democratizes finance, enhances security and transparency, and fosters continuous innovation. As we proceed through this presentation, we'll explore the various components and services of DeFi in detail, shedding light on how they are transforming the financial landscape.
At Intelisync, we specialize in providing comprehensive DeFi development services tailored to meet the unique needs of our clients. From smart contract development to dApp creation and security audits, we ensure that your DeFi project is built with innovation, security, and scalability in mind. Trust Intelisync to guide you through the intricate landscape of decentralized finance and unlock the full potential of blockchain technology.
Ready to take your DeFi project to the next level? Partner with Intelisync for expert DeFi development services today!
Main news related to the CCS TSI 2023 (2023/1695)Jakub Marek
An English 🇬🇧 translation of a presentation to the speech I gave about the main changes brought by CCS TSI 2023 at the biggest Czech conference on Communications and signalling systems on Railways, which was held in Clarion Hotel Olomouc from 7th to 9th November 2023 (konferenceszt.cz). Attended by around 500 participants and 200 on-line followers.
The original Czech 🇨🇿 version of the presentation can be found here: https://www.slideshare.net/slideshow/hlavni-novinky-souvisejici-s-ccs-tsi-2023-2023-1695/269688092 .
The videorecording (in Czech) from the presentation is available here: https://youtu.be/WzjJWm4IyPk?si=SImb06tuXGb30BEH .
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on integration of Salesforce with Bonterra Impact Management.
Interested in deploying an integration with Salesforce for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Tatiana Kojar
Skybuffer AI, built on the robust SAP Business Technology Platform (SAP BTP), is the latest and most advanced version of our AI development, reaffirming our commitment to delivering top-tier AI solutions. Skybuffer AI harnesses all the innovative capabilities of the SAP BTP in the AI domain, from Conversational AI to cutting-edge Generative AI and Retrieval-Augmented Generation (RAG). It also helps SAP customers safeguard their investments into SAP Conversational AI and ensure a seamless, one-click transition to SAP Business AI.
With Skybuffer AI, various AI models can be integrated into a single communication channel such as Microsoft Teams. This integration empowers business users with insights drawn from SAP backend systems, enterprise documents, and the expansive knowledge of Generative AI. And the best part of it is that it is all managed through our intuitive no-code Action Server interface, requiring no extensive coding knowledge and making the advanced AI accessible to more users.
Skybuffer SAM4U tool for SAP license adoptionTatiana Kojar
Manage and optimize your license adoption and consumption with SAM4U, an SAP free customer software asset management tool.
SAM4U, an SAP complimentary software asset management tool for customers, delivers a detailed and well-structured overview of license inventory and usage with a user-friendly interface. We offer a hosted, cost-effective, and performance-optimized SAM4U setup in the Skybuffer Cloud environment. You retain ownership of the system and data, while we manage the ABAP 7.58 infrastructure, ensuring fixed Total Cost of Ownership (TCO) and exceptional services through the SAP Fiori interface.
Ivanti’s Patch Tuesday breakdown goes beyond patching your applications and brings you the intelligence and guidance needed to prioritize where to focus your attention first. Catch early analysis on our Ivanti blog, then join industry expert Chris Goettl for the Patch Tuesday Webinar Event. There we’ll do a deep dive into each of the bulletins and give guidance on the risks associated with the newly-identified vulnerabilities.
HCL Notes and Domino License Cost Reduction in the World of DLAUpanagenda
Webinar Recording: https://www.panagenda.com/webinars/hcl-notes-and-domino-license-cost-reduction-in-the-world-of-dlau/
The introduction of DLAU and the CCB & CCX licensing model caused quite a stir in the HCL community. As a Notes and Domino customer, you may have faced challenges with unexpected user counts and license costs. You probably have questions on how this new licensing approach works and how to benefit from it. Most importantly, you likely have budget constraints and want to save money where possible. Don’t worry, we can help with all of this!
We’ll show you how to fix common misconfigurations that cause higher-than-expected user counts, and how to identify accounts which you can deactivate to save money. There are also frequent patterns that can cause unnecessary cost, like using a person document instead of a mail-in for shared mailboxes. We’ll provide examples and solutions for those as well. And naturally we’ll explain the new licensing model.
Join HCL Ambassador Marc Thomas in this webinar with a special guest appearance from Franz Walder. It will give you the tools and know-how to stay on top of what is going on with Domino licensing. You will be able lower your cost through an optimized configuration and keep it low going forward.
These topics will be covered
- Reducing license cost by finding and fixing misconfigurations and superfluous accounts
- How do CCB and CCX licenses really work?
- Understanding the DLAU tool and how to best utilize it
- Tips for common problem areas, like team mailboxes, functional/test users, etc
- Practical examples and best practices to implement right away
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfflufftailshop
When it comes to unit testing in the .NET ecosystem, developers have a wide range of options available. Among the most popular choices are NUnit, XUnit, and MSTest. These unit testing frameworks provide essential tools and features to help ensure the quality and reliability of code. However, understanding the differences between these frameworks is crucial for selecting the most suitable one for your projects.
Generating privacy-protected synthetic data using Secludy and MilvusZilliz
During this demo, the founders of Secludy will demonstrate how their system utilizes Milvus to store and manipulate embeddings for generating privacy-protected synthetic data. Their approach not only maintains the confidentiality of the original data but also enhances the utility and scalability of LLMs under privacy constraints. Attendees, including machine learning engineers, data scientists, and data managers, will witness first-hand how Secludy's integration with Milvus empowers organizations to harness the power of LLMs securely and efficiently.
Have you ever been confused by the myriad of choices offered by AWS for hosting a website or an API?
Lambda, Elastic Beanstalk, Lightsail, Amplify, S3 (and more!) can each host websites + APIs. But which one should we choose?
Which one is cheapest? Which one is fastest? Which one will scale to meet our needs?
Join me in this session as we dive into each AWS hosting service to determine which one is best for your scenario and explain why!
Monitoring and Managing Anomaly Detection on OpenShift.pdfTosin Akinosho
Monitoring and Managing Anomaly Detection on OpenShift
Overview
Dive into the world of anomaly detection on edge devices with our comprehensive hands-on tutorial. This SlideShare presentation will guide you through the entire process, from data collection and model training to edge deployment and real-time monitoring. Perfect for those looking to implement robust anomaly detection systems on resource-constrained IoT/edge devices.
Key Topics Covered
1. Introduction to Anomaly Detection
- Understand the fundamentals of anomaly detection and its importance in identifying unusual behavior or failures in systems.
2. Understanding Edge (IoT)
- Learn about edge computing and IoT, and how they enable real-time data processing and decision-making at the source.
3. What is ArgoCD?
- Discover ArgoCD, a declarative, GitOps continuous delivery tool for Kubernetes, and its role in deploying applications on edge devices.
4. Deployment Using ArgoCD for Edge Devices
- Step-by-step guide on deploying anomaly detection models on edge devices using ArgoCD.
5. Introduction to Apache Kafka and S3
- Explore Apache Kafka for real-time data streaming and Amazon S3 for scalable storage solutions.
6. Viewing Kafka Messages in the Data Lake
- Learn how to view and analyze Kafka messages stored in a data lake for better insights.
7. What is Prometheus?
- Get to know Prometheus, an open-source monitoring and alerting toolkit, and its application in monitoring edge devices.
8. Monitoring Application Metrics with Prometheus
- Detailed instructions on setting up Prometheus to monitor the performance and health of your anomaly detection system.
9. What is Camel K?
- Introduction to Camel K, a lightweight integration framework built on Apache Camel, designed for Kubernetes.
10. Configuring Camel K Integrations for Data Pipelines
- Learn how to configure Camel K for seamless data pipeline integrations in your anomaly detection workflow.
11. What is a Jupyter Notebook?
- Overview of Jupyter Notebooks, an open-source web application for creating and sharing documents with live code, equations, visualizations, and narrative text.
12. Jupyter Notebooks with Code Examples
- Hands-on examples and code snippets in Jupyter Notebooks to help you implement and test anomaly detection models.
Driving Business Innovation: Latest Generative AI Advancements & Success StorySafe Software
Are you ready to revolutionize how you handle data? Join us for a webinar where we’ll bring you up to speed with the latest advancements in Generative AI technology and discover how leveraging FME with tools from giants like Google Gemini, Amazon, and Microsoft OpenAI can supercharge your workflow efficiency.
During the hour, we’ll take you through:
Guest Speaker Segment with Hannah Barrington: Dive into the world of dynamic real estate marketing with Hannah, the Marketing Manager at Workspace Group. Hear firsthand how their team generates engaging descriptions for thousands of office units by integrating diverse data sources—from PDF floorplans to web pages—using FME transformers, like OpenAIVisionConnector and AnthropicVisionConnector. This use case will show you how GenAI can streamline content creation for marketing across the board.
Ollama Use Case: Learn how Scenario Specialist Dmitri Bagh has utilized Ollama within FME to input data, create custom models, and enhance security protocols. This segment will include demos to illustrate the full capabilities of FME in AI-driven processes.
Custom AI Models: Discover how to leverage FME to build personalized AI models using your data. Whether it’s populating a model with local data for added security or integrating public AI tools, find out how FME facilitates a versatile and secure approach to AI.
We’ll wrap up with a live Q&A session where you can engage with our experts on your specific use cases, and learn more about optimizing your data workflows with AI.
This webinar is ideal for professionals seeking to harness the power of AI within their data management systems while ensuring high levels of customization and security. Whether you're a novice or an expert, gain actionable insights and strategies to elevate your data processes. Join us to see how FME and AI can revolutionize how you work with data!
Programming Foundation Models with DSPy - Meetup SlidesZilliz
Prompting language models is hard, while programming language models is easy. In this talk, I will discuss the state-of-the-art framework DSPy for programming foundation models with its powerful optimizers and runtime constraint system.
This presentation provides valuable insights into effective cost-saving techniques on AWS. Learn how to optimize your AWS resources by rightsizing, increasing elasticity, picking the right storage class, and choosing the best pricing model. Additionally, discover essential governance mechanisms to ensure continuous cost efficiency. Whether you are new to AWS or an experienced user, this presentation provides clear and practical tips to help you reduce your cloud costs and get the most out of your budget.
Fueling AI with Great Data with Airbyte WebinarZilliz
This talk will focus on how to collect data from a variety of sources, leveraging this data for RAG and other GenAI use cases, and finally charting your course to productionalization.
In the rapidly evolving landscape of technologies, XML continues to play a vital role in structuring, storing, and transporting data across diverse systems. The recent advancements in artificial intelligence (AI) present new methodologies for enhancing XML development workflows, introducing efficiency, automation, and intelligent capabilities. This presentation will outline the scope and perspective of utilizing AI in XML development. The potential benefits and the possible pitfalls will be highlighted, providing a balanced view of the subject.
We will explore the capabilities of AI in understanding XML markup languages and autonomously creating structured XML content. Additionally, we will examine the capacity of AI to enrich plain text with appropriate XML markup. Practical examples and methodological guidelines will be provided to elucidate how AI can be effectively prompted to interpret and generate accurate XML markup.
Further emphasis will be placed on the role of AI in developing XSLT, or schemas such as XSD and Schematron. We will address the techniques and strategies adopted to create prompts for generating code, explaining code, or refactoring the code, and the results achieved.
The discussion will extend to how AI can be used to transform XML content. In particular, the focus will be on the use of AI XPath extension functions in XSLT, Schematron, Schematron Quick Fixes, or for XML content refactoring.
The presentation aims to deliver a comprehensive overview of AI usage in XML development, providing attendees with the necessary knowledge to make informed decisions. Whether you’re at the early stages of adopting AI or considering integrating it in advanced XML development, this presentation will cover all levels of expertise.
By highlighting the potential advantages and challenges of integrating AI with XML development tools and languages, the presentation seeks to inspire thoughtful conversation around the future of XML development. We’ll not only delve into the technical aspects of AI-powered XML development but also discuss practical implications and possible future directions.
Introduction of Cybersecurity with OSS at Code Europe 2024Hiroshi SHIBATA
I develop the Ruby programming language, RubyGems, and Bundler, which are package managers for Ruby. Today, I will introduce how to enhance the security of your application using open-source software (OSS) examples from Ruby and RubyGems.
The first topic is CVE (Common Vulnerabilities and Exposures). I have published CVEs many times. But what exactly is a CVE? I'll provide a basic understanding of CVEs and explain how to detect and handle vulnerabilities in OSS.
Next, let's discuss package managers. Package managers play a critical role in the OSS ecosystem. I'll explain how to manage library dependencies in your application.
I'll share insights into how the Ruby and RubyGems core team works to keep our ecosystem safe. By the end of this talk, you'll have a better understanding of how to safeguard your code.
Introduction of Cybersecurity with OSS at Code Europe 2024
Creating a Facebook Clone - Part XXII - Transcript.pdf
1. Creating a Facebook Clone - Part XXII
UserService is a big class and it makes sense to cover in two parts
2. setProps(user, u);
if (u.getPassword() != null) {
u.setPassword(encoder.encode(user.getPassword()));
}
users.save(u);
}
public byte[] getAvatar(String userId) {
User u = users.findById(userId).get();
if (u.getAvatar() != null) {
return u.getAvatar().getData();
}
return null;
}
public void setAvatar(String authToken, String mediaId) {
Media m = medias.findById(mediaId).get();
User u = users.findByAuthtoken(authToken).get(0);
u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
UserService
Next on the agenda is getAvatar, it returns the avatar picture of the user as a byte array
3. setProps(user, u);
if (u.getPassword() != null) {
u.setPassword(encoder.encode(user.getPassword()));
}
users.save(u);
}
public byte[] getAvatar(String userId) {
User u = users.findById(userId).get();
if (u.getAvatar() != null) {
return u.getAvatar().getData();
}
return null;
}
public void setAvatar(String authToken, String mediaId) {
Media m = medias.findById(mediaId).get();
User u = users.findByAuthtoken(authToken).get(0);
u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
UserService
Notice we need an id and not a token to get the avatar as anyone who is familiar with the user ID should be able to see the avatar
4. setProps(user, u);
if (u.getPassword() != null) {
u.setPassword(encoder.encode(user.getPassword()));
}
users.save(u);
}
public byte[] getAvatar(String userId) {
User u = users.findById(userId).get();
if (u.getAvatar() != null) {
return u.getAvatar().getData();
}
return null;
}
public void setAvatar(String authToken, String mediaId) {
Media m = medias.findById(mediaId).get();
User u = users.findByAuthtoken(authToken).get(0);
u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
UserService
If the avatar reference is null we return null instantly
5. setProps(user, u);
if (u.getPassword() != null) {
u.setPassword(encoder.encode(user.getPassword()));
}
users.save(u);
}
public byte[] getAvatar(String userId) {
User u = users.findById(userId).get();
if (u.getAvatar() != null) {
return u.getAvatar().getData();
}
return null;
}
public void setAvatar(String authToken, String mediaId) {
Media m = medias.findById(mediaId).get();
User u = users.findByAuthtoken(authToken).get(0);
u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
UserService
The setAvatar method works in a similar way
6. setProps(user, u);
if (u.getPassword() != null) {
u.setPassword(encoder.encode(user.getPassword()));
}
users.save(u);
}
public byte[] getAvatar(String userId) {
User u = users.findById(userId).get();
if (u.getAvatar() != null) {
return u.getAvatar().getData();
}
return null;
}
public void setAvatar(String authToken, String mediaId) {
Media m = medias.findById(mediaId).get();
User u = users.findByAuthtoken(authToken).get(0);
u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
UserService
Notice that unlike getAvatar with setAvatar we need a token as this is a set operation. This prevents other users from changing our avatar.
When we map this to the webservice we need to first create a media entry and only then set the avatar value.
7. u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
UserService
The friend request includes a few moving parts. First we need to send a request.
8. u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
UserService
We need an auth token as this is a secure operation
9. u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
UserService
We obviously don't have the auth token of the person we are "friending"
10. u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
UserService
This is a special case where we modify his entity without an auth-token, that's a bit risky...
11. u.setAvatar(m);
users.save(u);
}
public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
UserService
The notification service should notify the user that he got a new friend request. We'll dig into the notification service soon…
12. public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
UserService
But first lets check out the other side of the equation. The acceptFriendRequest method.
13. public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
UserService
This time me & him are flipped
14. public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
UserService
This checks against a potential weakness where a hacker could potentially call accept friend request for a person that didn't request it
15. public void sendFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
him.getFriendRequests().add(me);
users.save(him);
notifications.sendNotification(him,
new NotificationDAO(null, me.getDAO(),
"wants to be friends",
"uE7FC", 0x587EBE,
0, true, null, null));
}
public void acceptFriendRequest(String auth, String userId) {
User me = users.findByAuthtoken(auth).get(0);
User him = users.findById(userId).get();
if (me.getFriendRequests().contains(him)) {
me.getFriendRequests().remove(him);
me.getFriends().add(him);
him.getFriendRequests().remove(me);
him.getFriends().add(me);
users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
UserService
When a request is accepted we need to update the friend list on both sides. I didn't add a removeFriendRequest method which I probably should have added. I think it's
trivial to add so I'm leaving it as an exercise.
16. users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
User u = users.findByAuthtoken(auth).get(0);
if (c == null || c == 0) {
List<ShadowUser> shadowList = new ArrayList<>();
for (ShadowUserDAO d : contacts) {
shadowList.add(new ShadowUser(d, u));
updatePeopleYouMayKnow(d, u);
}
shadows.saveAll(shadowList);
} else {
for (ShadowUserDAO d : contacts) {
List<ShadowUser> results = shadows.findByFullName(auth, d.
getFullName());
if (!results.isEmpty()) {
shadows.save(new ShadowUser(d, u));
} else {
ShadowUser current = results.get(0);
current.setEmail(d.getEmail());
current.setPhone(d.getPhone());
current.setSecondaryPhone(d.getSecondaryPhone());
shadows.save(current);
UserService
The last method for UserService is the `uploadContacts` method...
It's invoked when the user uploads the contacts from his phone.
17. users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
User u = users.findByAuthtoken(auth).get(0);
if (c == null || c == 0) {
List<ShadowUser> shadowList = new ArrayList<>();
for (ShadowUserDAO d : contacts) {
shadowList.add(new ShadowUser(d, u));
updatePeopleYouMayKnow(d, u);
}
shadows.saveAll(shadowList);
} else {
for (ShadowUserDAO d : contacts) {
List<ShadowUser> results = shadows.findByFullName(auth, d.
getFullName());
if (!results.isEmpty()) {
shadows.save(new ShadowUser(d, u));
} else {
ShadowUser current = results.get(0);
current.setEmail(d.getEmail());
current.setPhone(d.getPhone());
current.setSecondaryPhone(d.getSecondaryPhone());
shadows.save(current);
UserService
If we uploaded contacts in the past its a good idea to try and merge with what we have. We can check that by running a count query
18. users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
User u = users.findByAuthtoken(auth).get(0);
if (c == null || c == 0) {
List<ShadowUser> shadowList = new ArrayList<>();
for (ShadowUserDAO d : contacts) {
shadowList.add(new ShadowUser(d, u));
updatePeopleYouMayKnow(d, u);
}
shadows.saveAll(shadowList);
} else {
for (ShadowUserDAO d : contacts) {
List<ShadowUser> results = shadows.findByFullName(auth, d.
getFullName());
if (!results.isEmpty()) {
shadows.save(new ShadowUser(d, u));
} else {
ShadowUser current = results.get(0);
current.setEmail(d.getEmail());
current.setPhone(d.getPhone());
current.setSecondaryPhone(d.getSecondaryPhone());
shadows.save(current);
UserService
For every contact we find we check to see if there is a user in the system and if so we add that user to the people you may know list
19. users.saveAll(Arrays.asList(me, him));
}
}
public void uploadContacts(String auth, List<ShadowUserDAO> contacts) {
Long c = shadows.countByUser(auth);
User u = users.findByAuthtoken(auth).get(0);
if (c == null || c == 0) {
List<ShadowUser> shadowList = new ArrayList<>();
for (ShadowUserDAO d : contacts) {
shadowList.add(new ShadowUser(d, u));
updatePeopleYouMayKnow(d, u);
}
shadows.saveAll(shadowList);
} else {
for (ShadowUserDAO d : contacts) {
List<ShadowUser> results = shadows.findByFullName(auth, d.
getFullName());
if (!results.isEmpty()) {
shadows.save(new ShadowUser(d, u));
} else {
ShadowUser current = results.get(0);
current.setEmail(d.getEmail());
current.setPhone(d.getPhone());
current.setSecondaryPhone(d.getSecondaryPhone());
shadows.save(current);
UserService
When adding a lot of elements using saveAll is much faster than save
20. if (c == null || c == 0) {
List<ShadowUser> shadowList = new ArrayList<>();
for (ShadowUserDAO d : contacts) {
shadowList.add(new ShadowUser(d, u));
updatePeopleYouMayKnow(d, u);
}
shadows.saveAll(shadowList);
} else {
for (ShadowUserDAO d : contacts) {
List<ShadowUser> results = shadows.findByFullName(auth, d.
getFullName());
if (!results.isEmpty()) {
shadows.save(new ShadowUser(d, u));
} else {
ShadowUser current = results.get(0);
current.setEmail(d.getEmail());
current.setPhone(d.getPhone());
current.setSecondaryPhone(d.getSecondaryPhone());
shadows.save(current);
updatePeopleYouMayKnow(d, u);
}
}
}
}
private void updatePeopleYouMayKnow(ShadowUserDAO d, User u) {
UserService
For simplicity I chose to merge based on full name. In retrospect it might have been wiser to use the device unique ID for every contact but that might breed duplicates
too.
I oversimplified a very complex process of handling shadow users. If you take the time to build something like this then make sure to analyze the data more thoroughly
and create a more robust social graph.
25. }
}
}
private User findHim(ShadowUserDAO d) {
if (d.getEmail() != null) {
List<User> l = users.findByEmailIgnoreCase(d.getEmail());
if (l != null && !l.isEmpty()) {
return l.get(0);
}
}
if (d.getPhone() != null) {
List<User> l = users.findByPhone(d.getPhone());
if (l != null && !l.isEmpty()) {
return l.get(0);
}
}
if (d.getSecondaryPhone() != null) {
List<User> l = users.findByPhone(d.getSecondaryPhone());
if (l != null && !l.isEmpty()) {
return l.get(0);
}
}
return null;
}
}
UserService
The findHim method is simple boilerplate that searches based on all the meta data in the shadow user. We use findByEmail/phone etc. to find the shadow user in our
regular user database.
With that we finished the UserService class which is the largest service class!