add openhack files
This commit is contained in:
588
support/datainit/MYDrivingDB.sql
Normal file
588
support/datainit/MYDrivingDB.sql
Normal file
@ -0,0 +1,588 @@
|
||||
/****** Object: Table [dbo].[Devices] Script Date: 3/24/2016 7:53:08 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Devices]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[Devices](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[Name] [nvarchar](max) NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
[UserProfile_Id] [nvarchar](128) NULL,
|
||||
CONSTRAINT [PK_dbo.Devices] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Index [IX_CreatedAt] Script Date: 3/24/2016 7:53:08 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Devices]') AND name = N'IX_CreatedAt')
|
||||
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [dbo].[Devices]
|
||||
(
|
||||
[CreatedAt] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
/****** Object: Table [dbo].[factMLOutputData] Script Date: 3/24/2016 7:53:08 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[factMLOutputData]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[factMLOutputData](
|
||||
[id] [int] IDENTITY(1,1) NOT NULL,
|
||||
[tripId] [nvarchar](50) NULL,
|
||||
[userId] [nvarchar](50) NULL,
|
||||
[tripstarttime] [nvarchar](50) NULL,
|
||||
[driverType] [nvarchar](50) NULL,
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Table [dbo].[IOTHubDatas] Script Date: 3/24/2016 7:53:09 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[IOTHubDatas]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[IOTHubDatas](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
CONSTRAINT [PK_dbo.IOTHubDatas] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Index [IX_CreatedAt] Script Date: 3/24/2016 7:53:09 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[IOTHubDatas]') AND name = N'IX_CreatedAt')
|
||||
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [dbo].[IOTHubDatas]
|
||||
(
|
||||
[CreatedAt] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
/****** Object: Table [dbo].[POIs] Script Date: 3/24/2016 7:53:09 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[POIs]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[POIs](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[TripId] [nvarchar](128) NULL,
|
||||
[Latitude] [float] NOT NULL,
|
||||
[Longitude] [float] NOT NULL,
|
||||
[POIType] [int] NOT NULL,
|
||||
[RecordedTimeStamp] [nvarchar](50) NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
[Timestamp] [datetime] NOT NULL,
|
||||
CONSTRAINT [PK_dbo.POIs] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Table [dbo].[TripPoints] Script Date: 3/24/2016 7:53:10 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TripPoints]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[TripPoints](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[TripId] [nvarchar](128) NULL,
|
||||
[Latitude] [float] NOT NULL,
|
||||
[Longitude] [float] NOT NULL,
|
||||
[Speed] [float] NOT NULL,
|
||||
[RecordedTimeStamp] [datetime] NOT NULL,
|
||||
[Sequence] [int] NOT NULL,
|
||||
[RPM] [float] NOT NULL,
|
||||
[ShortTermFuelBank] [float] NOT NULL,
|
||||
[LongTermFuelBank] [float] NOT NULL,
|
||||
[ThrottlePosition] [float] NOT NULL,
|
||||
[RelativeThrottlePosition] [float] NOT NULL,
|
||||
[Runtime] [float] NOT NULL,
|
||||
[DistanceWithMalfunctionLight] [float] NOT NULL,
|
||||
[EngineLoad] [float] NOT NULL,
|
||||
[MassFlowRate] [float] NOT NULL,
|
||||
[EngineFuelRate] [float] NOT NULL,
|
||||
[VIN] [nvarchar](max) NULL,
|
||||
[HasOBDData] [bit] NOT NULL,
|
||||
[HasSimulatedOBDData] [bit] NOT NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
CONSTRAINT [PK_dbo.TripPoints] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Index [IX_CreatedAt] Script Date: 3/24/2016 7:53:13 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[TripPoints]') AND name = N'IX_CreatedAt')
|
||||
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [dbo].[TripPoints]
|
||||
(
|
||||
[CreatedAt] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
/****** Object: Table [dbo].[Trips] Script Date: 3/24/2016 7:53:13 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Trips]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[Trips](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[Name] [nvarchar](max) NULL,
|
||||
[UserId] [nvarchar](128) NULL,
|
||||
[RecordedTimeStamp] [datetime] NOT NULL,
|
||||
[EndTimeStamp] [datetime] NOT NULL,
|
||||
[Rating] [int] NOT NULL,
|
||||
[IsComplete] [bit] NOT NULL,
|
||||
[HasSimulatedOBDData] [bit] NOT NULL,
|
||||
[AverageSpeed] [float] NOT NULL,
|
||||
[FuelUsed] [float] NOT NULL,
|
||||
[HardStops] [bigint] NOT NULL,
|
||||
[HardAccelerations] [bigint] NOT NULL,
|
||||
[MainPhotoUrl] [nvarchar](max) NULL,
|
||||
[Distance] [float] NOT NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
CONSTRAINT [PK_dbo.Trips] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Index [IX_CreatedAt] Script Date: 3/24/2016 7:53:15 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Trips]') AND name = N'IX_CreatedAt')
|
||||
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [dbo].[Trips]
|
||||
(
|
||||
[CreatedAt] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
/****** Object: Table [dbo].[UserProfiles] Script Date: 3/24/2016 7:53:15 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UserProfiles]') AND type in (N'U'))
|
||||
BEGIN
|
||||
CREATE TABLE [dbo].[UserProfiles](
|
||||
[Id] [nvarchar](128) NOT NULL,
|
||||
[FirstName] [nvarchar](max) NULL,
|
||||
[LastName] [nvarchar](max) NULL,
|
||||
[UserId] [nvarchar](max) NULL,
|
||||
[ProfilePictureUri] [nvarchar](max) NULL,
|
||||
[Rating] [int] NOT NULL,
|
||||
[Ranking] [int] NOT NULL,
|
||||
[TotalDistance] [float] NOT NULL,
|
||||
[TotalTrips] [bigint] NOT NULL,
|
||||
[TotalTime] [bigint] NOT NULL,
|
||||
[HardStops] [bigint] NOT NULL,
|
||||
[HardAccelerations] [bigint] NOT NULL,
|
||||
[FuelConsumption] [float] NOT NULL,
|
||||
[MaxSpeed] [float] NOT NULL,
|
||||
[Version] [timestamp] NOT NULL,
|
||||
[CreatedAt] [datetimeoffset](7) NOT NULL,
|
||||
[UpdatedAt] [datetimeoffset](7) NULL,
|
||||
[Deleted] [bit] NOT NULL,
|
||||
CONSTRAINT [PK_dbo.UserProfiles] PRIMARY KEY NONCLUSTERED
|
||||
(
|
||||
[Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
|
||||
)
|
||||
END
|
||||
GO
|
||||
/****** Object: Index [IX_CreatedAt] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[UserProfiles]') AND name = N'IX_CreatedAt')
|
||||
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [dbo].[UserProfiles]
|
||||
(
|
||||
[CreatedAt] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
SET ANSI_PADDING ON
|
||||
|
||||
GO
|
||||
/****** Object: Index [IX_UserProfile_Id] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Devices]') AND name = N'IX_UserProfile_Id')
|
||||
CREATE NONCLUSTERED INDEX [IX_UserProfile_Id] ON [dbo].[Devices]
|
||||
(
|
||||
[UserProfile_Id] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
SET ANSI_PADDING ON
|
||||
|
||||
GO
|
||||
/****** Object: Index [IX_TripId] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[TripPoints]') AND name = N'IX_TripId')
|
||||
CREATE NONCLUSTERED INDEX [IX_TripId] ON [dbo].[TripPoints]
|
||||
(
|
||||
[TripId] ASC
|
||||
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF)
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__Devices__Id__4E88ABD4]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.Devices')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[Devices] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__Devices__Created__4F7CD00D]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.Devices')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[Devices] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__IOTHubDatas__Id__36B12243]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.IOTHubDatas')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[IOTHubDatas] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__IOTHubDat__Creat__37A5467C]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.IOTHubDatas')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[IOTHubDatas] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__POIs__Id__3B75D760]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.POIs')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[POIs] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__POIs__CreatedAt__3C69FB99]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.POIs')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[POIs] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__POIs__Timestamp__5535A963]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Timestamp' AND object_id = object_id('dbo.POIs')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[POIs] ADD DEFAULT ('1900-01-01T00:00:00.000') FOR [Timestamp]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__TripPoints__Id__403A8C7D]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.TripPoints')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[TripPoints] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__TripPoint__Creat__412EB0B6]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.TripPoints')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[TripPoints] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__Trips__Id__44FF419A]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.Trips')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[Trips] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__Trips__CreatedAt__45F365D3]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.Trips')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[Trips] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__UserProfiles__Id__49C3F6B7]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='Id' AND object_id = object_id('dbo.UserProfiles')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[UserProfiles] ADD DEFAULT (newid()) FOR [Id]
|
||||
END
|
||||
|
||||
GO
|
||||
--IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DF__UserProfi__Creat__4AB81AF0]') AND type = 'D')
|
||||
IF (SELECT object_definition(default_object_id) AS definition FROM sys.columns WHERE name ='CreatedAt' AND object_id = object_id('dbo.UserProfiles')) IS NULL
|
||||
BEGIN
|
||||
ALTER TABLE [dbo].[UserProfiles] ADD DEFAULT (sysutcdatetime()) FOR [CreatedAt]
|
||||
END
|
||||
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.Devices_dbo.UserProfiles_UserProfile_Id]') AND parent_object_id = OBJECT_ID(N'[dbo].[Devices]'))
|
||||
ALTER TABLE [dbo].[Devices] WITH CHECK ADD CONSTRAINT [FK_dbo.Devices_dbo.UserProfiles_UserProfile_Id] FOREIGN KEY([UserProfile_Id])
|
||||
REFERENCES [dbo].[UserProfiles] ([Id])
|
||||
GO
|
||||
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.Devices_dbo.UserProfiles_UserProfile_Id]') AND parent_object_id = OBJECT_ID(N'[dbo].[Devices]'))
|
||||
ALTER TABLE [dbo].[Devices] CHECK CONSTRAINT [FK_dbo.Devices_dbo.UserProfiles_UserProfile_Id]
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.TripPoints_dbo.Trips_TripId]') AND parent_object_id = OBJECT_ID(N'[dbo].[TripPoints]'))
|
||||
ALTER TABLE [dbo].[TripPoints] WITH CHECK ADD CONSTRAINT [FK_dbo.TripPoints_dbo.Trips_TripId] FOREIGN KEY([TripId])
|
||||
REFERENCES [dbo].[Trips] ([Id])
|
||||
GO
|
||||
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_dbo.TripPoints_dbo.Trips_TripId]') AND parent_object_id = OBJECT_ID(N'[dbo].[TripPoints]'))
|
||||
ALTER TABLE [dbo].[TripPoints] CHECK CONSTRAINT [FK_dbo.TripPoints_dbo.Trips_TripId]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[TR_dbo_Devices_InsertUpdateDelete] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TR_dbo_Devices_InsertUpdateDelete]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[TR_dbo_Devices_InsertUpdateDelete] ON [dbo].[Devices] AFTER INSERT, UPDATE, DELETE AS BEGIN UPDATE [dbo].[Devices] SET [dbo].[Devices].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED WHERE inserted.[Id] = [dbo].[Devices].[Id] END'
|
||||
GO
|
||||
ALTER TABLE [dbo].[Devices] ENABLE TRIGGER [TR_dbo_Devices_InsertUpdateDelete]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[UpdateRatings] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[UpdateRatings]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[UpdateRatings] ON [dbo].[factMLOutputData]
|
||||
FOR INSERT
|
||||
AS
|
||||
-- Do it for all rows (maybe bulk insert) inserted
|
||||
DECLARE crs CURSOR FOR
|
||||
SELECT userId FROM inserted
|
||||
|
||||
DECLARE @UId varchar(100)
|
||||
|
||||
OPEN crs
|
||||
FETCH NEXT FROM crs INTO @UId
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
|
||||
WITH all_scores AS (
|
||||
SELECT userId, COUNT(driverType) as a_s FROM dbo.factMLOutputData GROUP BY userId),
|
||||
good_scores AS (
|
||||
SELECT userId, COUNT(driverType) as g_s FROM dbo.factMLOutputData WHERE driverType = ''Good'' GROUP BY userId),
|
||||
ratings AS (
|
||||
SELECT all_scores.userId as ui, CAST( (100 * g_s)/a_s AS INT) as r FROM all_scores, good_scores WHERE all_scores.userId = good_scores.userId)
|
||||
|
||||
UPDATE UserProfiles SET UserProfiles.Rating = ratings.r FROM ratings WHERE UserProfiles.UserId = ratings.ui AND UserProfiles.UserId = @UId;
|
||||
|
||||
FETCH NEXT FROM crs INTO @UId
|
||||
END
|
||||
CLOSE crs
|
||||
DEALLOCATE crs'
|
||||
GO
|
||||
ALTER TABLE [dbo].[factMLOutputData] ENABLE TRIGGER [UpdateRatings]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[TR_dbo_IOTHubDatas_InsertUpdateDelete] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TR_dbo_IOTHubDatas_InsertUpdateDelete]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[TR_dbo_IOTHubDatas_InsertUpdateDelete] ON [dbo].[IOTHubDatas] AFTER INSERT, UPDATE, DELETE AS BEGIN UPDATE [dbo].[IOTHubDatas] SET [dbo].[IOTHubDatas].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED WHERE inserted.[Id] = [dbo].[IOTHubDatas].[Id] END'
|
||||
GO
|
||||
ALTER TABLE [dbo].[IOTHubDatas] ENABLE TRIGGER [TR_dbo_IOTHubDatas_InsertUpdateDelete]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[UpdateUserProfilesOnInsert] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[TR_dbo_TripPoints_InsertUpdateDelete] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TR_dbo_TripPoints_InsertUpdateDelete]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[TR_dbo_TripPoints_InsertUpdateDelete] ON [dbo].[TripPoints] AFTER INSERT, UPDATE, DELETE AS BEGIN UPDATE [dbo].[TripPoints] SET [dbo].[TripPoints].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED WHERE inserted.[Id] = [dbo].[TripPoints].[Id] END'
|
||||
GO
|
||||
ALTER TABLE [dbo].[TripPoints] ENABLE TRIGGER [TR_dbo_TripPoints_InsertUpdateDelete]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[TR_dbo_Trips_InsertUpdateDelete] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TR_dbo_Trips_InsertUpdateDelete]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[TR_dbo_Trips_InsertUpdateDelete] ON [dbo].[Trips] AFTER INSERT, UPDATE, DELETE AS BEGIN UPDATE [dbo].[Trips] SET [dbo].[Trips].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED WHERE inserted.[Id] = [dbo].[Trips].[Id] END'
|
||||
GO
|
||||
ALTER TABLE [dbo].[Trips] ENABLE TRIGGER [TR_dbo_Trips_InsertUpdateDelete]
|
||||
GO
|
||||
/****** Object: Trigger [dbo].[TR_dbo_UserProfiles_InsertUpdateDelete] Script Date: 3/24/2016 7:53:17 PM ******/
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
GO
|
||||
IF NOT EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[TR_dbo_UserProfiles_InsertUpdateDelete]'))
|
||||
EXEC dbo.sp_executesql @statement = N'CREATE TRIGGER [dbo].[TR_dbo_UserProfiles_InsertUpdateDelete] ON [dbo].[UserProfiles] AFTER INSERT, UPDATE, DELETE AS BEGIN UPDATE [dbo].[UserProfiles] SET [dbo].[UserProfiles].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED WHERE inserted.[Id] = [dbo].[UserProfiles].[Id] END'
|
||||
GO
|
||||
ALTER TABLE [dbo].[UserProfiles] ENABLE TRIGGER [TR_dbo_UserProfiles_InsertUpdateDelete]
|
||||
GO
|
||||
|
||||
|
||||
/******* Adding Additional Tables Needed for Simulator *********************/
|
||||
|
||||
GO
|
||||
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;
|
||||
|
||||
SET NUMERIC_ROUNDABORT OFF;
|
||||
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Creating [dbo].[POISource]...';
|
||||
|
||||
|
||||
GO
|
||||
CREATE TABLE [dbo].[POISource] (
|
||||
[Id] NVARCHAR (128) NOT NULL,
|
||||
[TripId] NVARCHAR (MAX) NULL,
|
||||
[Latitude] FLOAT (53) NOT NULL,
|
||||
[Longitude] FLOAT (53) NOT NULL,
|
||||
[POIType] INT NOT NULL,
|
||||
[RecordedTimeStamp] NVARCHAR (50) NULL,
|
||||
CONSTRAINT [PK_POISource_ID] PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||
);
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Creating [dbo].[TripPointSource]...';
|
||||
|
||||
|
||||
GO
|
||||
CREATE TABLE [dbo].[TripPointSource] (
|
||||
[tripid] VARCHAR (36) NOT NULL,
|
||||
[userid] VARCHAR (33) NOT NULL,
|
||||
[name] VARCHAR (30) NULL,
|
||||
[trippointid] VARCHAR (36) NOT NULL,
|
||||
[lat] NUMERIC (18, 15) NOT NULL,
|
||||
[lon] NUMERIC (19, 14) NOT NULL,
|
||||
[speed] INT NOT NULL,
|
||||
[recordedtimestamp] VARCHAR (28) NOT NULL,
|
||||
[sequence] INT NOT NULL,
|
||||
[enginerpm] INT NOT NULL,
|
||||
[shorttermfuelbank] INT NOT NULL,
|
||||
[longtermfuelbank] INT NOT NULL,
|
||||
[throttleposition] INT NOT NULL,
|
||||
[relativethrottleposition] INT NOT NULL,
|
||||
[runtime] INT NOT NULL,
|
||||
[distancewithmil] INT NOT NULL,
|
||||
[engineload] INT NOT NULL,
|
||||
[mafflowrate] INT NOT NULL,
|
||||
[outsidetemperature] VARCHAR (30) NULL,
|
||||
[enginefuelrate] INT NOT NULL,
|
||||
[FIELD21] INT NULL,
|
||||
PRIMARY KEY CLUSTERED ([trippointid] ASC)
|
||||
);
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Creating [dbo].[POIs].[nci_wi_POIs_55307BFB0FFEEFC3E0238C0CC3B42651]...';
|
||||
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [nci_wi_POIs_55307BFB0FFEEFC3E0238C0CC3B42651]
|
||||
ON [dbo].[POIs]([POIType] ASC)
|
||||
INCLUDE([TripId]);
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Creating unnamed constraint on [dbo].[IOTHubDatas]...';
|
||||
|
||||
|
||||
GO
|
||||
ALTER TABLE [dbo].[IOTHubDatas]
|
||||
ADD DEFAULT ((0)) FOR [Deleted];
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Creating unnamed constraint on [dbo].[POIs]...';
|
||||
|
||||
|
||||
GO
|
||||
ALTER TABLE [dbo].[POIs]
|
||||
ADD DEFAULT ((0)) FOR [Deleted];
|
||||
|
||||
|
||||
GO
|
||||
PRINT N'Altering [dbo].[UpdateUserProfilesOnInsert]...';
|
||||
|
||||
|
||||
GO
|
||||
ALTER TRIGGER [dbo].[UpdateUserProfilesOnInsert] ON [dbo].[POIs]
|
||||
FOR INSERT
|
||||
AS
|
||||
-- Do it for all rows inserted (maybe bulk insert)
|
||||
DECLARE crs CURSOR FOR
|
||||
SELECT TripId FROM inserted
|
||||
|
||||
DECLARE @TId nvarchar(100)
|
||||
|
||||
OPEN crs
|
||||
FETCH NEXT FROM crs INTO @TId
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
|
||||
-- Update Accelerations
|
||||
WITH ascnt1 AS (
|
||||
SELECT p.TripId, up.UserId, COUNT(p.POIType) AS cnt1
|
||||
FROM dbo.POIs AS p INNER JOIN
|
||||
dbo.Trips AS t ON p.TripId = t.Id INNER JOIN
|
||||
dbo.UserProfiles AS up ON t.UserId = up.UserId
|
||||
WHERE (p.POIType = 1)
|
||||
GROUP BY p.TripId, up.UserId
|
||||
)
|
||||
UPDATE dbo.UserProfiles SET dbo.UserProfiles.HardAccelerations = ascnt1.cnt1 FROM ascnt1
|
||||
WHERE ascnt1.TripId = @TId AND dbo.UserProfiles.UserId = ascnt1.UserId;
|
||||
|
||||
-- Update Hard Stops
|
||||
WITH ascnt2 AS (
|
||||
SELECT p.TripId, up.UserId, COUNT(p.POIType) AS cnt2
|
||||
FROM dbo.POIs AS p INNER JOIN
|
||||
dbo.Trips AS t ON p.TripId = t.Id INNER JOIN
|
||||
dbo.UserProfiles AS up ON t.UserId = up.UserId
|
||||
WHERE (p.POIType = 2)
|
||||
GROUP BY p.TripId, up.UserId
|
||||
)
|
||||
UPDATE dbo.UserProfiles SET dbo.UserProfiles.HardStops = ascnt2.cnt2 FROM ascnt2
|
||||
WHERE ascnt2.TripId = @TId AND dbo.UserProfiles.UserId = ascnt2.UserId;
|
||||
|
||||
|
||||
FETCH NEXT FROM crs INTO @TId
|
||||
END
|
||||
CLOSE crs
|
||||
DEALLOCATE crs
|
||||
GO
|
||||
PRINT N'Creating [dbo].[GetPoisForTrip]...';
|
||||
|
||||
|
||||
GO
|
||||
|
||||
PRINT N'Update complete.';
|
||||
|
||||
|
||||
GO
|
3098
support/datainit/MyDrivingDB-SampleTripData.sql
Normal file
3098
support/datainit/MyDrivingDB-SampleTripData.sql
Normal file
File diff suppressed because it is too large
Load Diff
3
support/datainit/data_load/Devices_export.txt
Normal file
3
support/datainit/data_load/Devices_export.txt
Normal file
@ -0,0 +1,3 @@
|
||||
3c2d2032-2b47-4f5d-8ce5-c5ca7f3946e0,E9D9F26C1FF94E99AD54E46C599F239E,0000000000E351E1,2018-04-19 14:48:54.0819652 +00:00,2018-06-11 19:22:07.5001365 +00:00,0,aa1d876a-3e37-4a7a-8c9b-769ee6217ec1
|
||||
9fecda48-101e-47f2-adf0-d62ccd6e5bb3,AwAy9AgAuvUFAPkCBQCxDQUA7BgFAA3bBgABAAQAwggEAMDjBAB2gEAmqACAAS8CQAkSA,0000000000E351E3,2018-04-30 22:28:32.4461915 +00:00,2018-06-11 19:22:07.5001365 +00:00,0,aa1d876a-3e37-4a7a-8c9b-769ee6217ec1
|
||||
f495f983-2498-4111-ad04-9477e03a9766,5EEBF77002C648CEAE2C00A8D13D080F,0000000000E351E5,2018-05-03 18:29:12.6235231 +00:00,2018-06-11 19:22:07.5001365 +00:00,0,aa1d876a-3e37-4a7a-8c9b-769ee6217ec1
|
0
support/datainit/data_load/IOTHubDatas_export.txt
Normal file
0
support/datainit/data_load/IOTHubDatas_export.txt
Normal file
142
support/datainit/data_load/POISource_export.txt
Normal file
142
support/datainit/data_load/POISource_export.txt
Normal file
@ -0,0 +1,142 @@
|
||||
012ADABA-E54A-4E7B-9825-57B102BD28F6,SampleTrip-1,47.68411072981651,-122.09753371796079,1,2018-04-19T22:41:44.0000106Z
|
||||
01302DAB-AAA7-415C-8952-96B329B03508,SampleTrip-1,47.667247618290041,-122.1223678869641,2,2018-04-19T22:27:59.0009726Z
|
||||
0265BAEE-D2C5-402C-8EE0-33589DF50072,SampleTrip-1,47.669481581626513,-122.1074391850682,2,2018-04-19T22:33:08.0002016Z
|
||||
0481ADB9-860C-4C1C-A769-94CFF832185F,SampleTrip-1,47.667590868659808,-122.11021959615299,2,2018-04-19T22:31:28.0006766Z
|
||||
06805D39-1132-4191-81A3-281419C01190,SampleTrip-1,47.693662081044025,-122.09450435449531,1,2018-04-19T22:43:39.0008836Z
|
||||
08013950-5FFB-4BF7-8548-95570A6A1DBA,SampleTrip-1,47.667296327896004,-122.1117333490477,2,2018-04-19T22:30:46.0007646Z
|
||||
08AF0734-FAA6-485F-A71B-08B8AA7718FA,SampleTrip-1,47.646196796161213,-122.13233643420783,2,2018-04-19T22:20:13.0000536Z
|
||||
0A17142A-42AF-429C-9E8B-45CB93B9B611,SampleTrip-1,47.663409073391939,-122.13358850856919,1,2018-04-19T22:25:12.0008146Z
|
||||
0D39F23E-7FF7-40D5-92AD-D36844546520,SampleTrip-1,47.642636232633365,-122.13065412308404,2,2018-04-19T22:15:50.0007826Z
|
||||
0EAF8F56-8C95-4F5C-B99A-21863C3EFF9A,SampleTrip-1,47.668099786196208,-122.1091324057823,2,2018-04-19T22:32:29.0005836Z
|
||||
128047C2-EFF5-4D8B-B9F4-82AFE024EC0B,SampleTrip-1,47.652633207065136,-122.13734972151691,2,2018-04-19T22:23:06.0004926Z
|
||||
130B9D24-73B3-4BF6-8BB8-54DB9FB465AD,SampleTrip-1,47.647213639203521,-122.13482900750259,1,2018-04-19T22:20:48.0000446Z
|
||||
175B6C02-B101-4DB1-975E-F1B6295F923B,SampleTrip-1,47.668648904439976,-122.1082794293,2,2018-04-19T22:32:48.0006136Z
|
||||
1B6C2EC4-5819-4F02-A9D7-C2A38B31E9A5,SampleTrip-1,47.669236247563234,-122.10763998906042,2,2018-04-19T22:33:00.0002976Z
|
||||
1F10C9C5-821C-4C22-AB90-F17F8A7EE19C,SampleTrip-1,47.64450859984612,-122.13205113440867,2,2018-04-19T22:16:57.0007076Z
|
||||
1F750B58-9ADD-4C6B-943C-3C74F0095E6E,SampleTrip-1,47.646931062654865,-122.13465742836274,1,2018-04-19T22:20:44.0007986Z
|
||||
21C527D2-E02E-40A2-A457-E7508265E8C3,SampleTrip-1,47.685253586327313,-122.09604222059937,2,2018-04-19T22:41:56.0009916Z
|
||||
28077305-9065-4669-9D7D-18AC2E90FA1A,SampleTrip-1,47.687256866668207,-122.09354471471012,2,2018-04-19T22:42:39.0006496Z
|
||||
2822D832-4774-48BD-B6D6-4C91947BEE6F,SampleTrip-1,47.682203121029069,-122.09999760361764,2,2018-04-19T22:40:51.0004536Z
|
||||
2A0A5E1D-6E5B-40C9-95C2-A811BEF98A1A,SampleTrip-1,47.669996751797029,-122.10707167704082,2,2018-04-19T22:34:24.0004946Z
|
||||
2AFCD93B-6EF7-4D00-B98D-F1ADCD2B906E,SampleTrip-1,47.642949886735856,-122.13205376351259,2,2018-04-19T22:16:37.0001476Z
|
||||
2C03AAE7-6DA9-4333-9A43-ACBE6FA0949E,SampleTrip-2,47.669353068545725,-122.10780910106263,2,2018-04-20T16:55:43.0003740Z
|
||||
2D4DD733-875C-4F2C-B34B-98CD1023848A,SampleTrip-1,47.659316670509831,-122.13575754895695,1,2018-04-19T22:23:46.0001346Z
|
||||
30E79A58-1E4B-4823-A7B7-F681B094B61B,SampleTrip-1,47.645689644587627,-122.1322441073502,2,2018-04-19T22:18:38.0005816Z
|
||||
321AC6B2-7738-4D4E-9EC4-22432F3F325D,SampleTrip-1,47.662389196280365,-122.13417667064076,2,2018-04-19T22:24:58.0006056Z
|
||||
322FBEC2-00A6-46B1-BC99-2B09E2BA9E19,SampleTrip-1,47.660879554870426,-122.1348833407789,1,2018-04-19T22:24:32.0008186Z
|
||||
33227492-B0BA-477D-B197-AEF2379979A9,SampleTrip-1,47.645514470576352,-122.13202500298458,2,2018-04-19T22:17:09.0008166Z
|
||||
34B5B0D1-47C7-4046-82E6-77E73117FC5C,SampleTrip-1,47.664068606516373,-122.13304956925374,2,2018-04-19T22:25:20.0002356Z
|
||||
35117AF0-F387-4BE3-9AB1-3BE1F45D07AE,SampleTrip-1,47.667169468169213,-122.11270420046787,1,2018-04-19T22:29:27.0006426Z
|
||||
375825F8-614F-4A9E-BEFC-468FB499BFA9,SampleTrip-1,47.645764575393358,-122.13229222751795,2,2018-04-19T22:18:47.0006056Z
|
||||
390072F4-8E1A-4C2B-967C-7642E07D2552,SampleTrip-1,47.667165373290594,-122.11602638445471,1,2018-04-19T22:28:53.0002116Z
|
||||
39759C2E-BB17-494E-99E2-110381FD209E,SampleTrip-1,47.671682607641259,-122.10638324658845,1,2018-04-19T22:34:49.0007276Z
|
||||
398B3AB6-F590-48B3-995F-1100B1766A00,SampleTrip-1,47.669543492477885,-122.10740227904095,2,2018-04-19T22:33:11.0009326Z
|
||||
3BE2C067-11D4-451B-8FD4-B9FF77040DA3,SampleTrip-1,47.666650830367125,-122.12905755995651,2,2018-04-19T22:26:17.0009726Z
|
||||
3CA96256-6D62-4DC0-9B0A-6B5A26BDA734,SampleTrip-1,47.658511424686921,-122.13624016641609,1,2018-04-19T22:23:39.0007096Z
|
||||
3EBCDF24-9B2B-4381-8820-87B1BC81F2E1,SampleTrip-1,47.686027628398776,-122.09516229251933,1,2018-04-19T22:42:17.0000106Z
|
||||
3EDC909E-EDB0-4553-AC96-9F5FC3ED8C01,SampleTrip-1,47.669655867000913,-122.10732227026298,1,2018-04-19T22:33:16.0009686Z
|
||||
3EE9E52E-1DCA-40A4-BB15-02D0376B78F8,SampleTrip-1,47.641490168545424,-122.13056892118045,2,2018-04-19T22:15:29.0000856Z
|
||||
3F8D400D-D36A-4A73-B432-1A4BC8C75CFE,SampleTrip-1,47.682162639103304,-122.10005527386416,2,2018-04-19T22:40:49.0004916Z
|
||||
429CEDF1-9025-469F-ABA9-4D2DC628BE4C,SampleTrip-1,47.692987503144145,-122.09313236500898,1,2018-04-19T22:43:26.0003866Z
|
||||
4470275A-FFF6-4E7B-BD2C-8365ECB4EA3A,SampleTrip-1,47.661703353094666,-122.13447567065802,1,2018-04-19T22:24:48.0002766Z
|
||||
44C074C1-8CDF-4B45-96BA-9F8C76A71EEB,SampleTrip-1,47.687605438021357,-122.0931279829108,2,2018-04-19T22:42:42.0001476Z
|
||||
473EE303-9F10-4532-A454-6A835679309E,SampleTrip-1,47.667270231430123,-122.12479024680418,2,2018-04-19T22:27:27.0006476Z
|
||||
47DCABEA-432F-44A2-AC28-1E9EB903CFCA,SampleTrip-1,47.668920947695291,-122.10797162220351,1,2018-04-19T22:32:53.0004546Z
|
||||
4A16D0F3-32BC-4F2E-855C-ADE413418BF7,SampleTrip-1,47.672009380956155,-122.10624735091885,2,2018-04-19T22:35:12.0008886Z
|
||||
4B244F8E-976D-41D0-863F-904B7A6DB71D,SampleTrip-1,47.669741020745313,-122.10722447909086,2,2018-04-19T22:33:47.0009506Z
|
||||
4C441D26-FE6D-4A53-8C2D-86DB82A8CFFB,SampleTrip-1,47.660613069339071,-122.13503408035119,2,2018-04-19T22:24:23.0005666Z
|
||||
4CDDD5F4-9C9F-4F76-898C-A0870D787E3F,SampleTrip-1,47.671908752313435,-122.10626769498082,2,2018-04-19T22:35:02.0006586Z
|
||||
4D567B2C-69F4-4ADC-8B30-00DDAA545CAA,SampleTrip-1,47.674911520891257,-122.10579545692791,2,2018-04-19T22:38:33.0002446Z
|
||||
50C96B00-32FC-44A0-B951-63426F3E6B25,SampleTrip-1,47.689281995610777,-122.09195724391445,2,2018-04-19T22:42:54.0001786Z
|
||||
510832C5-879D-487F-87A1-FF9BE966BCED,SampleTrip-1,47.646295526157594,-122.13420670405195,1,2018-04-19T22:20:35.0001986Z
|
||||
51D0E007-9C76-4C34-853E-D6E4DCA906B9,SampleTrip-1,47.669307835197401,-122.10757154434633,2,2018-04-19T22:33:02.0009216Z
|
||||
526535C3-9754-4648-879F-F84D65FD2652,SampleTrip-1,47.683584106759469,-122.09828309123934,2,2018-04-19T22:41:38.0000216Z
|
||||
559CF885-AE46-4485-A413-74AE381DCEF7,SampleTrip-1,47.671379496282533,-122.10649237047669,2,2018-04-19T22:34:44.0003926Z
|
||||
57A8A2AF-D2FE-4B71-80E2-982082C5C4E0,SampleTrip-1,47.640678255950256,-122.13052354597433,2,2018-04-19T22:15:22.0008226Z
|
||||
589F4B89-EB90-4416-95FC-F802A4EB51F8,SampleTrip-1,47.66231873999002,-122.13419617889437,2,2018-04-19T22:24:57.0002436Z
|
||||
5B50CDFF-8D83-4D05-B662-7E48861A5739,SampleTrip-1,47.647538859378457,-122.13502063475788,2,2018-04-19T22:21:12.0009986Z
|
||||
5D45E868-1327-4FB7-AF10-3CC55EB9B8D3,SampleTrip-1,47.650013465425275,-122.13636924832451,1,2018-04-19T22:22:53.0006486Z
|
||||
5EF838E8-08B6-4089-B792-4B9ED9E4695C,SampleTrip-1,47.682805029793009,-122.09938048180315,2,2018-04-19T22:41:29.0002056Z
|
||||
5FCE51BC-7584-4A99-ADC3-53E821EE99F5,SampleTrip-1,47.661898950391702,-122.13435705657209,1,2018-04-19T22:24:51.0004796Z
|
||||
630F898E-FEE4-48C0-8E16-0FC68A0E1AE4,SampleTrip-1,47.642828218452998,-122.13079345159586,1,2018-04-19T22:15:59.0008826Z
|
||||
69016D00-A313-45A8-8D61-73B247FCC7F2,SampleTrip-1,47.692377586092526,-122.09257621219149,1,2018-04-19T22:43:16.0002666Z
|
||||
6982C8AB-396E-40E7-A86F-1D72F54B4889,SampleTrip-1,47.685350451657506,-122.09591824650086,1,2018-04-19T22:41:57.0002476Z
|
||||
6C96E6F4-8288-40F8-81F6-1E942002417D,SampleTrip-1,47.677994665168924,-122.10514938573776,2,2018-04-19T22:38:59.0008416Z
|
||||
6CF587AB-D41A-4A61-95F5-A5B3A88B4DD4,SampleTrip-1,47.645482519189123,-122.13223868735328,2,2018-04-19T22:18:34.0002306Z
|
||||
6D7F6359-5E81-454B-A933-802B68815F93,SampleTrip-1,47.657735958389495,-122.13674681335627,1,2018-04-19T22:23:34.0001136Z
|
||||
6F742DFB-B376-4E4E-AD42-590E8532247F,SampleTrip-1,47.686574952551403,-122.09441934916282,1,2018-04-19T22:42:32.0009346Z
|
||||
729F8A38-8D6D-4D2E-8302-FBAD1884EB62,SampleTrip-1,47.669609222534653,-122.10736035508761,2,2018-04-19T22:33:14.0009746Z
|
||||
72F41E09-5077-4BB7-B54A-0E980DAEC267,SampleTrip-1,47.667148026473811,-122.11271963003664,1,2018-04-19T22:29:24.0001176Z
|
||||
7948A9D0-630A-4E4D-B725-7ECEE799E028,SampleTrip-2,47.667253767790179,-122.11295111569861,1,2018-04-20T16:56:02.0009260Z
|
||||
79B7A1A9-0B83-4E1A-B6DA-C46A1509EED1,SampleTrip-1,47.650822359793246,-122.13672973477929,2,2018-04-19T22:22:57.0001516Z
|
||||
7B037D27-CCDC-4B8F-9245-B466EF99DAA5,SampleTrip-2,47.675870004171017,-122.10614585243928,2,2018-04-20T16:55:03.0004360Z
|
||||
7FA18EAD-322B-436E-AFEB-703B2BEBBDC9,SampleTrip-1,47.685056095537675,-122.09628355620909,2,2018-04-19T22:41:54.0001276Z
|
||||
823D5836-F7B4-4E09-B2AC-21CEB2C8BFB5,SampleTrip-1,47.651032217491732,-122.1368180184264,2,2018-04-19T22:22:58.0008046Z
|
||||
848F7E3F-1934-4895-B7C8-0AF9E0DD7AA8,SampleTrip-1,47.67220387440247,-122.10616371970694,2,2018-04-19T22:36:17.0007716Z
|
||||
863D5ADF-40CB-4BAF-99F2-CDC87DE87749,SampleTrip-1,47.643160290473553,-122.13206106458041,1,2018-04-19T22:16:45.0008796Z
|
||||
86982AC6-4E52-4642-A0E6-63063CCC523C,SampleTrip-1,47.674032997702405,-122.10574813842685,2,2018-04-19T22:38:22.0000606Z
|
||||
86BD04A3-71C5-416F-9C36-ED046E31B6F0,SampleTrip-1,47.645247547544173,-122.13206153253984,1,2018-04-19T22:17:04.0002066Z
|
||||
86DC2350-75B2-4B32-914C-F5274AE23DE9,SampleTrip-1,47.678077955396041,-122.10505171679694,2,2018-04-19T22:39:00.0000346Z
|
||||
8D93FFB1-2F49-43CF-B153-5358E81F11A8,SampleTrip-1,47.681557446137717,-122.10086059213282,1,2018-04-19T22:40:12.0006786Z
|
||||
9200E556-EA5F-41FE-9546-33D78B964E1D,SampleTrip-1,47.666085195219509,-122.130503684443,2,2018-04-19T22:25:54.0004146Z
|
||||
9208FF51-96AD-478F-8B5F-9D6C84E890E4,SampleTrip-1,47.660570339428979,-122.13506264369454,1,2018-04-19T22:24:21.0001136Z
|
||||
940AF093-5997-4274-9ED3-256BB32B17AA,SampleTrip-1,47.686498899227644,-122.09452678043115,2,2018-04-19T22:42:31.0007666Z
|
||||
970FC717-A007-4616-ACA5-4C2B51313042,SampleTrip-1,47.645799136391489,-122.13227525041899,2,2018-04-19T22:18:43.0008566Z
|
||||
97A35712-C113-46E3-BABD-0E90CD93880E,SampleTrip-1,47.689760843207246,-122.09176771251917,1,2018-04-19T22:42:57.0000696Z
|
||||
9A3747CC-AD19-45E4-A436-8E1C6DEB8E2F,SampleTrip-1,47.667006822421101,-122.12764812574437,1,2018-04-19T22:26:37.0003166Z
|
||||
9A957507-3ACB-46DA-BEF1-4D3458940F91,SampleTrip-1,47.667238970401968,-122.12180597315736,1,2018-04-19T22:28:05.0009706Z
|
||||
9D1F1D70-103C-4801-8A22-014B565EB98F,SampleTrip-1,47.640544424478463,-122.13052070894442,1,2018-04-19T22:15:21.0009146Z
|
||||
A0E27F14-9178-45F2-BEE9-AABAC24AA728,SampleTrip-1,47.642857480828546,-122.13193336158847,1,2018-04-19T22:16:23.0001936Z
|
||||
A1F310F8-1005-4237-9B9F-0384BEE96044,SampleTrip-1,47.667128396203047,-122.11250178481077,1,2018-04-19T22:29:48.0001236Z
|
||||
A6C7D75D-A83C-436B-A008-57BF154B81EF,SampleTrip-1,47.642852256723486,-122.13126930166086,2,2018-04-19T22:16:03.0006486Z
|
||||
A703E1CA-AA9F-4C93-A2B4-CBA29E7754E7,SampleTrip-1,47.685701632032114,-122.09547565930589,1,2018-04-19T22:42:01.0003656Z
|
||||
A841B868-A108-4243-86EE-9AAC6665731E,SampleTrip-1,47.645316204347964,-122.13225784278974,2,2018-04-19T22:18:31.0000356Z
|
||||
A8843651-2BE5-40F0-A68A-DEAC01FB8DDB,SampleTrip-1,47.681763921264341,-122.10059558775946,2,2018-04-19T22:40:36.0009716Z
|
||||
A9124BE5-31CA-4A4A-A865-A020D438AFBD,SampleTrip-1,47.655311096796225,-122.13770104750036,1,2018-04-19T22:23:20.0007736Z
|
||||
AA1CCEB6-360F-4E3A-9042-38854CFB9DB6,SampleTrip-1,47.646315405775866,-122.13381271511534,1,2018-04-19T22:20:28.0009886Z
|
||||
AB7CC555-7543-4B3D-8F2F-B4619563845F,SampleTrip-1,47.647488997105029,-122.13501310494568,2,2018-04-19T22:21:05.0002126Z
|
||||
ACA18D8E-8ACB-460E-8356-EBD686EF64FE,SampleTrip-1,47.671799238415659,-122.10632003626475,2,2018-04-19T22:34:54.0009186Z
|
||||
AED25115-1D18-424A-B5E7-5515D0906F7E,SampleTrip-1,47.643392124296362,-122.13204837727353,2,2018-04-19T22:16:48.0006956Z
|
||||
B388C2D2-2121-40F8-AE81-E10FF19456C6,SampleTrip-1,47.672035864245387,-122.10624148155534,1,2018-04-19T22:35:47.0008866Z
|
||||
B40380A3-6095-4255-AAFF-29A997C92C78,SampleTrip-1,47.652826691468057,-122.13744534133565,1,2018-04-19T22:23:07.0004016Z
|
||||
B50D12B6-2D60-407F-94F1-856E57F02FA7,SampleTrip-1,47.647952654287579,-122.1353160745838,2,2018-04-19T22:22:10.0008306Z
|
||||
B7817514-102F-43C1-9475-B505868771EF,SampleTrip-1,47.681466028842991,-122.10096004991611,1,2018-04-19T22:40:06.0005816Z
|
||||
B9B3180B-0141-489F-851D-77691376CC9A,SampleTrip-1,47.690263235265249,-122.09165568111251,2,2018-04-19T22:43:00.0007306Z
|
||||
B9C375B6-405D-4E5F-A36E-33F46E42A510,SampleTrip-1,47.681604690983335,-122.100814406298,1,2018-04-19T22:40:15.0000806Z
|
||||
BADF3C49-122D-4307-BE58-C44F4546295A,SampleTrip-1,47.693342751579166,-122.09409297883212,2,2018-04-19T22:43:34.0000756Z
|
||||
BB17E10F-D2DD-41D0-9006-9C160728ED07,SampleTrip-1,47.671100768268261,-122.1065861954165,1,2018-04-19T22:34:40.0008386Z
|
||||
BE102F1E-88C1-4164-93B3-19051E9BDAED,SampleTrip-1,47.660303013616556,-122.13518703017463,1,2018-04-19T22:24:12.0000046Z
|
||||
BEDE5038-383D-4619-9718-D8B608C69F2A,SampleTrip-1,47.669846829906014,-122.10721268002766,1,2018-04-19T22:34:01.0004876Z
|
||||
BF80570A-F864-45E7-B00B-C9FD1927FAE6,SampleTrip-1,47.643077782656981,-122.13206846266571,1,2018-04-19T22:16:43.0009316Z
|
||||
C6978400-BFCC-494C-9DFC-69AACC457806,SampleTrip-1,47.64269009218475,-122.13065456579427,1,2018-04-19T22:15:53.0007206Z
|
||||
C76A6A4C-2F39-49B3-8B1E-DB5A2C1CF5E0,SampleTrip-1,47.675436195333269,-122.10584486180338,2,2018-04-19T22:38:38.0000646Z
|
||||
C870EC91-30CB-4ACE-B696-3059514D72AD,SampleTrip-1,47.668131101255085,-122.10908233553971,1,2018-04-19T22:32:33.0006416Z
|
||||
C9FD923D-1916-4C84-A69D-C573412FA27E,SampleTrip-1,47.646518012271862,-122.13441838228681,1,2018-04-19T22:20:39.0000316Z
|
||||
CA281907-FF6C-4FEE-9611-2BFF0FB35183,SampleTrip-1,47.660522914236353,-122.13509278485824,1,2018-04-19T22:24:19.0007896Z
|
||||
CC254D32-4210-447D-89C0-1A97E58C1A53,SampleTrip-1,47.646294575278873,-122.13398236183072,2,2018-04-19T22:20:31.0002986Z
|
||||
CCCBE045-3342-4808-AD8D-A63982BF5525,SampleTrip-1,47.670067011252009,-122.10702790437563,2,2018-04-19T22:34:26.0003636Z
|
||||
CD349527-06DD-425A-BC8A-0E37875EB971,SampleTrip-1,47.667025029660444,-122.12753516638209,2,2018-04-19T22:26:39.0007776Z
|
||||
CE1D84A1-01BB-43B1-BC44-51F5D6DE1B84,SampleTrip-1,47.692441022827502,-122.09261392332823,1,2018-04-19T22:43:17.0008136Z
|
||||
CF447B37-AE8D-4D6A-BF44-FFC8A0C2666B,SampleTrip-1,47.683056042197173,-122.09906704340902,1,2018-04-19T22:41:32.0000626Z
|
||||
D2B57EE0-B1B1-4066-80C4-99D2697665DF,SampleTrip-1,47.666575844952931,-122.12928942236604,1,2018-04-19T22:26:14.0009876Z
|
||||
D451E544-789B-4CB8-9BE3-233461C2AE95,SampleTrip-1,47.6675308909685,-122.11038980511722,1,2018-04-19T22:31:25.0000956Z
|
||||
D58E1C3C-8398-467A-947F-5F4C81D0299F,SampleTrip-1,47.667271883866647,-122.11179420407817,1,2018-04-19T22:30:27.0009946Z
|
||||
D94C613B-3196-4B6F-81BE-D380754E3F43,SampleTrip-1,47.647775883094525,-122.13516529677754,2,2018-04-19T22:21:43.0005916Z
|
||||
DA5A1834-9F9F-4184-9055-47F77C21F2EC,SampleTrip-1,47.665536523907882,-122.1313823043195,2,2018-04-19T22:25:36.0007346Z
|
||||
E0D5E2B6-2165-43EB-8429-6DC79C73DE19,SampleTrip-1,47.684952783586944,-122.09640309234635,2,2018-04-19T22:41:53.0000966Z
|
||||
E20FC7FF-D828-4CCC-8A39-4F4FC062BC8C,SampleTrip-1,47.66712805499273,-122.12687414672733,1,2018-04-19T22:27:07.0008446Z
|
||||
E32BC2CC-3400-440E-9764-9BFE0B7B5F43,SampleTrip-1,47.642380126876681,-122.13062047561701,2,2018-04-19T22:15:42.0005696Z
|
||||
E39216E0-9E03-4803-865B-706D464DFA62,SampleTrip-1,47.640103658251064,-122.13052101303094,1,2018-04-19T22:15:17.0002576Z
|
||||
E59CD22D-B685-4475-B048-DBC3C2D991F0,SampleTrip-1,47.667076908569754,-122.12725953940148,1,2018-04-19T22:26:45.0004236Z
|
||||
E69689AD-B679-4E9D-900F-CD55AE1D2457,SampleTrip-1,47.687728113624651,-122.09299633895748,1,2018-04-19T22:42:43.0007236Z
|
||||
E74AB145-8926-40BE-8FD5-EE729960C6EB,SampleTrip-1,47.686306055221685,-122.09480984445598,1,2018-04-19T22:42:28.0008776Z
|
||||
E8041DC2-3E5C-497E-AE70-9A8D367938FC,SampleTrip-1,47.684370461393058,-122.09716771810341,1,2018-04-19T22:41:47.0004086Z
|
||||
E892A086-D374-4FA0-B2D6-8D3EA247ABD6,SampleTrip-1,47.659980384004314,-122.13532903059118,2,2018-04-19T22:24:03.0002366Z
|
||||
EA43351C-A3BB-471D-9867-C0FCA6DBA63F,SampleTrip-1,47.660464634037119,-122.13514210956237,1,2018-04-19T22:24:16.0006996Z
|
||||
EE1D9F43-432E-4AD4-9E9E-C05275D79917,SampleTrip-1,47.671960440506481,-122.1062564154563,1,2018-04-19T22:35:06.0006846Z
|
||||
F3B15F55-7394-413F-ABB9-F81CFA024980,SampleTrip-1,47.646595465488303,-122.13446389096195,2,2018-04-19T22:20:40.0007126Z
|
||||
F496F957-B643-45E0-BF51-769FACB04912,SampleTrip-2,47.675972292250485,-122.10619896628785,2,2018-04-20T16:54:41.0009200Z
|
||||
FBBBD6CA-7051-4686-BDEA-33FE1809FBE7,SampleTrip-1,47.646327992871271,-122.13325819441235,2,2018-04-19T22:20:23.0005066Z
|
||||
FD92E3B7-628A-4CDF-B715-72C55006DC04,SampleTrip-1,47.653836383969889,-122.13749305671205,2,2018-04-19T22:23:12.0007186Z
|
||||
FDBA638E-FA82-4314-A0C9-70D4FE58FD26,SampleTrip-1,47.640198965731763,-122.13051905884824,2,2018-04-19T22:15:18.0002536Z
|
||||
FFD0A69E-E629-4BAC-A344-D9E3FD23B67F,SampleTrip-1,47.669793783947767,-122.10721621795015,2,2018-04-19T22:33:50.0000126Z
|
2
support/datainit/data_load/POIs_export.txt
Normal file
2
support/datainit/data_load/POIs_export.txt
Normal file
@ -0,0 +1,2 @@
|
||||
264ffaa3-1fe8-4fb0-a4fb-63bdbc9999ae,ea2f7ae0-3cef-49cb-b7d1-ce972113120c,47.690263235265249,-122.09165568111251,2,3:00:20 AM,0000000000E351F0,2018-05-24 10:00:25.2475568 +00:00,,0,1900-01-01 00:00:00.000
|
||||
a7c2d2c6-e803-43a8-bf3d-340b7987e73a,ea2f7ae0-3cef-49cb-b7d1-ce972113120c,47.667148026473811,-122.11271963003664,1,3:00:20 AM,0000000000E351F6,2018-05-24 10:00:25.2475568 +00:00,,0,1900-01-01 00:00:00.000
|
2739
support/datainit/data_load/TripPointSource_export.txt
Normal file
2739
support/datainit/data_load/TripPointSource_export.txt
Normal file
File diff suppressed because it is too large
Load Diff
3
support/datainit/data_load/TripPoints_export.txt
Normal file
3
support/datainit/data_load/TripPoints_export.txt
Normal file
@ -0,0 +1,3 @@
|
||||
81730ad3-00be-4a47-9122-ef06721cffe5,ea2f7ae0-3cef-49cb-b7d1-ce972113120c,47.676030319787046,-122.10612586361655,0.0,2018-05-24 10:00:15.003,0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0,0,0000000000E351ED,2018-05-24 10:00:26.5444410 +00:00,2018-06-11 19:22:08.3126209 +00:00,0
|
||||
23dfc028-f84f-4230-b297-88a4bafb6c22,ea2f7ae0-3cef-49cb-b7d1-ce972113120c,47.675978287840387,-122.10611846546108,0.0,2018-05-24 10:00:15.003,1,720.0,-1.0,-4.0,16.0,6.0,665.0,0.0,16.0,5.0,-255.0,,0,0,0000000000E351EB,2018-05-24 10:00:29.9506830 +00:00,2018-06-11 19:22:08.3126209 +00:00,0
|
||||
cf77e286-9ffe-4f91-b07e-f9855d91dab5,ea2f7ae0-3cef-49cb-b7d1-ce972113120c,47.675978287840387,-122.10611846546108,-255.0,2018-05-24 10:00:15.003,2,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,-255.0,5.0,-255.0,,0,0,0000000000E351EF,2018-05-24 10:00:29.9506830 +00:00,2018-06-11 19:22:08.3126209 +00:00,0
|
1
support/datainit/data_load/Trips_export.txt
Normal file
1
support/datainit/data_load/Trips_export.txt
Normal file
@ -0,0 +1 @@
|
||||
ea2f7ae0-3cef-49cb-b7d1-ce972113120c,Trip 0,SomeUser,2018-05-24 10:00:15.003,2018-05-24 10:14:15.003,90,0,0,0.0,0.0,75,63,,5.9500000000000002,0000000000E351E8,2018-05-24 10:00:25.9350521 +00:00,2018-06-11 19:22:08.2501414 +00:00,0
|
1
support/datainit/data_load/UserProfiles_export.txt
Normal file
1
support/datainit/data_load/UserProfiles_export.txt
Normal file
@ -0,0 +1 @@
|
||||
aa1d876a-3e37-4a7a-8c9b-769ee6217ec1,Hacker,1,Hacker 1,https://pbs.twimg.com/profile_images/1003946090146693122/IdMjh-FQ_bigger.jpg,0,0,0.0,0,0,0,0,0.0,0.0,0000000000E351DE,2018-04-19 14:48:51.5976202 +00:00,2018-06-11 19:22:07.4532365 +00:00,0
|
16
support/datainit/data_load/data_export.sh
Normal file
16
support/datainit/data_load/data_export.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() { echo "Usage: sql_data_init.sh -s <SQL Server FQDN> -u <sql username> -p <sql password> " 1>&2; exit 1; }
|
||||
|
||||
bcp Devices out ~/Devices_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp factMLOutputData out ~/factMLOutputData_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp IOTHubDatas out ~/IOTHubDatas_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp POIs out ~/POIs_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp TripPoints out ~/TripPoints_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp Trips out ~/Trips_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp UserProfiles out ~/UserProfiles_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp POISource out ~/POISource_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
||||
bcp TripPointSource out ~/TripPointSource_export.txt -S teamdef93sql.database.windows.net -U teamdef93sa -P 2J2fn9Tl3pwd -d mydrivingDB -c -t ','
|
174
support/datainit/data_load/factMLOutputData_export.txt
Normal file
174
support/datainit/data_load/factMLOutputData_export.txt
Normal file
@ -0,0 +1,174 @@
|
||||
1,250fa603-031a-4321-99be-6f7536f5f200,ismihan-mk,3/12/2016 9:47:29 PM,Good
|
||||
2,3c39a0ca-ce61-441c-b54c-2414c47fd616,ismihan-mk,3/12/2016 8:15:01 PM,Good
|
||||
3,805780fe-8681-4777-82e4-6013da0ce470,davecraw-mk,3/12/2016 3:01:04 AM,Good
|
||||
4,f52d3886-6748-4238-bfe8-6d60e0ee8b22,ismihan-mk,3/12/2016 10:56:33 PM,Good
|
||||
5,003fc3f0-bd9b-4673-bd33-a343940a326d,1,3/20/2016 8:11:06 AM,Good
|
||||
6,14cb073b-f148-464e-96a1-6548208824f8,1,3/20/2016 4:10:57 PM,Good
|
||||
7,24c84e2d-ccd3-4e5d-af45-cf4361911c1d,1,3/20/2016 4:10:52 PM,Good
|
||||
8,2a203a61-9464-4682-8508-5b70baede7f7,1,3/20/2016 8:10:25 AM,Good
|
||||
9,322ecd58-f903-4e95-ae8f-cb6d690ea5ba,Facebook:203538940012375,3/20/2016 12:24:58 AM,Good
|
||||
10,3311f8ea-a8e4-4c3e-a0d2-2bd4943f6183,1,3/20/2016 4:11:09 PM,Good
|
||||
11,3677a316-2e44-4f4c-8294-e20684ec3e17,Facebook:203538940012375,3/20/2016 7:58:24 AM,Good
|
||||
12,38056345-39a2-474d-b5e4-18b978647470,Facebook:203538940012375,3/20/2016 7:59:38 AM,Good
|
||||
13,522b5c31-0750-4c61-8f68-42bcd6af123b,Facebook:203538940012375,3/20/2016 6:47:56 AM,Good
|
||||
14,69947721-da34-4c8f-af4b-54e4f7e69f00,Facebook:203538940012375,3/20/2016 8:46:23 AM,Good
|
||||
15,7628c48a-12bc-4fef-8b9f-9e2c32739d7c,1,3/20/2016 4:10:35 PM,Good
|
||||
16,79cad820-1ead-494b-be15-1a65bf342db8,Facebook:203538940012375,3/20/2016 7:37:35 AM,Good
|
||||
17,7a4f1137-a99a-48e7-bfa3-6a1037bcb449,1,3/20/2016 8:11:09 AM,Good
|
||||
18,7ddcffb7-1351-46ea-bd62-63232a541625,Twitter:19249356,3/20/2016 11:06:20 PM,Good
|
||||
19,81200e11-e4f8-40fc-a1cc-14848c388e46,1,3/20/2016 10:15:36 PM,Good
|
||||
20,814609ee-7b7a-4d32-9492-d2b2fddf49f8,Facebook:203538940012375,3/20/2016 5:41:23 PM,Good
|
||||
21,86e6e92b-a239-4e72-a8b2-802dafd1ff8a,Facebook:979553468780247,3/20/2016 10:54:20 PM,Good
|
||||
22,878e22d4-c451-4e0a-ac42-bf60b1ce9237,Facebook:203538940012375,3/20/2016 8:45:35 AM,Good
|
||||
23,8b8a8351-e0e6-489f-a3e3-8f0e2d6e7025,1,3/20/2016 2:00:38 AM,Good
|
||||
24,911a01c5-a5a4-4d12-988d-23fa44c88953,1,3/20/2016 8:10:23 AM,Good
|
||||
25,976a8901-e800-4c9d-a364-68fadf8f5ae5,1,3/20/2016 8:10:24 AM,Good
|
||||
26,98346ebc-96e7-4f8a-baf7-633a1e88344b,1,3/20/2016 8:10:50 AM,Good
|
||||
27,a0eb0031-c4af-4049-b225-798e3b08c8e1,Facebook:203538940012375,3/20/2016 6:07:02 AM,Good
|
||||
28,af3beb3a-4238-43e5-9a23-f6dc43e4ed10,Facebook:203538940012375,3/20/2016 8:45:50 AM,Good
|
||||
29,b0132ff6-8e92-4d7b-a6b3-0ceaef3f9afb,1,3/20/2016 12:03:00 AM,Good
|
||||
30,b1bdbefa-2833-4225-bde2-550041fbdaea,1,3/20/2016 4:11:17 PM,Good
|
||||
31,b4ce58cd-2191-470b-9454-bf4447b40d35,Facebook:203538940012375,3/18/2016 11:51:19 PM,Good
|
||||
32,b58afdba-f60b-42ae-bca9-8c4d7f74c6be,1,3/20/2016 4:10:56 PM,Good
|
||||
33,b8a3500c-89df-47a0-9a22-381e5acf3575,1,3/20/2016 8:10:59 AM,Good
|
||||
34,b94dca78-6859-47f5-bef1-a7f679bbaf89,1,3/20/2016 4:10:47 PM,Good
|
||||
35,c05899dd-267b-453b-b244-69445f71e3ce,1,3/20/2016 8:10:28 AM,Good
|
||||
36,c08d750e-d7e5-4afc-9514-dfb258f01a94,1,3/20/2016 8:11:01 AM,Good
|
||||
37,c0dcda52-a310-4632-ab77-94e783a8b2f0,Facebook:203538940012375,3/20/2016 9:23:19 AM,Good
|
||||
38,c6e149b4-ff1e-45d5-bbed-26bf42c5c115,Facebook:203538940012375,3/20/2016 6:45:49 AM,Good
|
||||
39,d2f1b183-44e9-48fa-8c29-a8374c797490,1,3/20/2016 4:10:37 PM,Good
|
||||
40,d7455553-bce5-4207-ab91-94e650562f81,1,3/20/2016 8:10:44 AM,Good
|
||||
41,da877def-9408-4852-b71b-bf1b109c105c,1,3/20/2016 8:10:47 AM,Good
|
||||
42,e6f97648-f834-42a6-8451-53651bec0eed,Facebook:203538940012375,3/20/2016 8:43:53 AM,Good
|
||||
43,f064e7f8-8e35-48e7-aa66-cc936486f9a2,Facebook:10156612592435524,3/20/2016 2:47:04 PM,Good
|
||||
44,f09627ce-5efc-4977-8172-855545334c58,1,3/20/2016 4:10:39 PM,Good
|
||||
45,f21413fb-d216-47e4-8b72-bf2ea7a2e7ef,1,3/20/2016 4:11:23 PM,Good
|
||||
46,f50dad83-430e-4e19-a959-647ba75bdfb1,Facebook:203538940012375,3/20/2016 8:46:03 AM,Good
|
||||
47,02f0a19c-4121-4996-b2e2-a529a8e737ab,1,3/19/2016 10:21:25 PM,Good
|
||||
48,05db1563-c0c0-47be-a114-808d0f9c7435,1,3/19/2016 8:10:53 AM,Good
|
||||
49,09229929-3d12-4b08-b7ff-c6404a3a9698,1,3/19/2016 8:30:01 PM,Good
|
||||
50,0bdc6eab-fe13-4b10-86de-da622ee11b0f,1,3/19/2016 8:30:15 PM,Good
|
||||
51,0bf56b26-4d3f-4fbd-80fa-bd7287301cdc,1,3/19/2016 8:30:03 PM,Good
|
||||
52,102af4de-72ca-4023-b574-936057ea0d98,1,3/19/2016 10:21:24 PM,Good
|
||||
53,135de4f7-8365-4548-9ff1-3f224ccc240e,Twitter:19249356,3/19/2016 11:21:18 PM,Good
|
||||
54,19ccdb5f-41c3-4b91-8dbb-69275c772a6a,Facebook:979553468780247,3/19/2016 12:51:36 AM,Good
|
||||
55,27e39c5b-e333-422c-8717-6fa01342f6b3,Twitter:19249356,3/19/2016 8:06:44 PM,Good
|
||||
56,27f01ca7-0bfa-4dd6-bf2a-689399335360,1,3/19/2016 8:31:15 PM,Good
|
||||
57,288fe3a6-6af0-435e-b01b-79f33824f667,Facebook:108531336210491,3/19/2016 12:34:33 AM,Good
|
||||
58,2b893449-0dfc-4c6d-a1d1-2f0c7752867f,1,3/19/2016 5:06:50 PM,Good
|
||||
59,2d67bdb9-49df-429c-b1c1-bfa2b1850f40,1,3/19/2016 4:11:16 PM,Good
|
||||
60,318f8f3f-2399-4775-8795-87561ee5b0c1,Facebook:160614340995675,3/19/2016 3:58:34 AM,Good
|
||||
61,324e0f75-d835-4e70-9366-8662a831145e,Facebook:203538940012375,3/19/2016 12:30:01 AM,Good
|
||||
62,335fd0c4-bb7f-42d7-85b8-6d7f89b3c62f,1,3/19/2016 7:57:59 PM,Good
|
||||
63,3518243b-58b0-4a5f-bedf-8a5ea2c86f9a,1,3/19/2016 8:30:27 PM,Good
|
||||
64,35fdc5de-e8a2-4173-bb56-3e8c75ad229f,1,3/19/2016 10:21:03 PM,Good
|
||||
65,39f11bb6-9d13-43b6-b73a-c6863f2f7a38,1,3/19/2016 4:10:25 PM,Good
|
||||
66,452d71ba-967c-431b-a801-128b39d1740a,1,3/19/2016 8:37:36 AM,Good
|
||||
67,47f40c3e-6aa5-4da4-86a1-4cc786796843,1,3/19/2016 8:37:21 AM,Good
|
||||
68,48c4544c-4e56-4606-929b-e998b7356ef5,Twitter:19249356,3/19/2016 10:54:43 PM,Good
|
||||
69,4a806886-2fd1-41d9-9313-4965b98b2c27,1,3/19/2016 8:29:05 AM,Good
|
||||
70,4b517c92-bea2-4cfa-a373-e7c19b9afcac,1,3/19/2016 9:28:05 PM,Good
|
||||
71,4b7d82f4-9cb3-4b8d-9983-bf83d1fa33c8,1,3/19/2016 5:56:11 PM,Good
|
||||
72,507bef68-5379-45b2-8aeb-682968d79015,1,3/19/2016 8:30:27 PM,Good
|
||||
73,51eeac6a-cbb2-4054-a34a-7c9db20671ea,Facebook:203538940012375,3/19/2016 12:13:36 AM,Good
|
||||
74,52ce8f00-dc36-493b-adf3-64e18dbcd4b1,1,3/19/2016 10:21:03 PM,Good
|
||||
75,52faaf07-6b8c-4b9a-831e-022bb1d10282,1,3/19/2016 8:49:18 AM,Good
|
||||
76,53a68cb9-3967-4954-bef3-a212ea4856c9,Facebook:1047585061949223,3/19/2016 2:15:36 AM,Good
|
||||
77,5597d06f-4451-4f04-b2ae-05898e79eb7f,1,3/19/2016 10:21:23 PM,Good
|
||||
78,55a7438d-bdf8-4f96-bf51-4ad05f4191cd,1,3/19/2016 9:28:18 PM,Good
|
||||
79,566de02b-b8cf-4806-8e03-6691d1f6f33b,1,3/19/2016 7:56:14 PM,Good
|
||||
80,5f710ba2-9f15-4470-bfe1-8fa8c5174006,Facebook:1047585061949223,3/19/2016 2:07:35 AM,Good
|
||||
81,5f96d65a-2fd1-425d-b938-4c2bb409777f,Facebook:203538940012375,3/19/2016 10:21:20 PM,Good
|
||||
82,64588dd6-e501-4648-bfde-c612177889fe,1,3/19/2016 4:11:50 PM,Good
|
||||
83,6770de7e-e717-428c-a484-29960a9f4b10,1,3/19/2016 8:30:14 PM,Good
|
||||
84,68c0c20c-eb5e-451c-99ad-e66329b7dd62,Facebook:203538940012375,3/19/2016 12:04:53 AM,Good
|
||||
85,741ca0ee-c8c4-4c13-b237-540766333196,1,3/19/2016 9:28:27 PM,Good
|
||||
86,7a6149e0-8967-477c-b977-099d34db13a0,1,3/19/2016 4:11:01 PM,Good
|
||||
87,88297fd1-3040-42dc-8656-8ed2b40a818c,Facebook:203538940012375,3/19/2016 7:44:04 PM,Good
|
||||
88,8a22e170-252f-46e3-b94c-6c07e970b312,Facebook:203538940012375,3/19/2016 12:23:16 AM,Good
|
||||
89,91086ba0-a6b8-4990-83d8-6d120466d22d,Facebook:979553468780247,3/19/2016 10:05:33 PM,Good
|
||||
90,946dbd4a-765b-459d-af9f-72ad7a4bbc94,1,3/19/2016 8:14:07 AM,Good
|
||||
91,96f3ce7f-f902-4f86-9cb8-f3b4e4e5bbdc,1,3/19/2016 8:22:02 AM,Good
|
||||
92,98264fd3-7af5-4b35-be95-90fa718bc284,1,3/19/2016 4:10:59 PM,Good
|
||||
93,9918c8c4-2427-40c4-96ce-19b6e7dfd532,1,3/19/2016 7:55:13 PM,Good
|
||||
94,9963fd65-3488-4cce-b810-3967efda4577,1,3/19/2016 8:30:31 PM,Good
|
||||
95,9b3fc6b7-6a2c-49ed-a197-85355d59b32c,Facebook:108531336210491,3/19/2016 3:46:33 AM,Good
|
||||
96,a35d18c2-5dda-4c4d-ad9e-dd8136079ff5,Facebook:203538940012375,3/19/2016 4:34:15 AM,Good
|
||||
97,a5e087d2-289c-4d22-ad89-97d69b208400,1,3/19/2016 9:28:45 PM,Good
|
||||
98,a95cc2ea-f8e4-4616-a25b-e591f720d6de,1,3/19/2016 10:21:21 PM,Good
|
||||
99,b08135e2-a3b4-4d61-9988-883fcc707a61,1,3/19/2016 7:56:22 PM,Good
|
||||
100,b158f1d4-6376-4859-a9d6-66f1b7e70840,1,3/19/2016 4:11:35 PM,Good
|
||||
101,b5580b7b-b95c-4c8c-82ee-ab9b1a598af3,1,3/19/2016 10:20:53 PM,Good
|
||||
102,b5e16315-4a20-44d3-a207-ee3582271795,Facebook:1221443151217187,3/19/2016 6:18:26 PM,Good
|
||||
103,bbeb5e77-7815-419a-9315-db887f00ba95,1,3/19/2016 10:21:11 PM,Good
|
||||
104,bdacff24-3981-4acf-905b-3f2ed6582764,1,3/19/2016 4:11:38 PM,Good
|
||||
105,c4ccb675-b7f9-4e51-96c0-dc24fc3a327e,1,3/19/2016 9:28:42 PM,Good
|
||||
106,c5aaf97f-1092-4b16-8332-28d21e0bf465,1,3/19/2016 8:30:54 PM,Good
|
||||
107,c6beb9de-4231-44b0-bb26-5a03969e7d4b,Facebook:1047585061949223,3/19/2016 2:46:43 AM,Good
|
||||
108,c8596bf1-6a8a-4186-a85d-966e8a00bce6,1,3/19/2016 8:30:58 PM,Good
|
||||
109,cade5c47-6380-4c29-8116-6179db668d7b,Twitter:19249356,3/19/2016 11:26:50 PM,Good
|
||||
110,cb3ad9cd-44b7-452e-8356-3eace54fd7d2,Facebook:203538940012375,3/19/2016 6:30:01 PM,Good
|
||||
111,cd7ba09d-0c10-4969-8f5d-4e41b4e1f849,1,3/19/2016 9:28:36 PM,Good
|
||||
112,d51f0747-5c39-4b5a-a29c-62b7c46f1480,1,3/19/2016 7:56:01 PM,Good
|
||||
113,d5efd317-9eb9-46da-9650-e4ba142166cb,1,3/19/2016 9:28:18 PM,Good
|
||||
114,d5f4808c-4910-4160-8401-2bf028182a42,Facebook:1221443151217187,3/19/2016 10:45:52 PM,Good
|
||||
115,d5f5b615-a545-4110-812c-7e02c46c16c4,1,3/19/2016 7:55:37 PM,Good
|
||||
116,e0bb996e-d0f4-4748-b9f3-1cc203fd0c50,1,3/19/2016 4:11:06 PM,Good
|
||||
117,e1511f69-c0a2-4563-98fc-fa4c7fd90146,1,3/19/2016 7:55:50 PM,Good
|
||||
118,e470f3fe-b90b-43ac-8c7d-b5d174a2a5a1,1,3/19/2016 8:30:35 PM,Good
|
||||
119,e756ced7-d63a-45f3-b820-bcc9678b9bbc,1,3/19/2016 7:55:50 PM,Good
|
||||
120,e784de92-a01e-49b1-bfd9-bdc61efe000d,1,3/19/2016 8:37:40 PM,Good
|
||||
121,ed216364-78cc-4c83-8c70-e2e02b5ef412,Facebook:203538940012375,3/19/2016 12:26:37 AM,Good
|
||||
122,eef727f2-c980-404b-b29e-b19e60495779,1,3/19/2016 7:56:06 PM,Good
|
||||
123,f1c7aad3-daa6-43d4-951b-931c78f2c81f,1,3/19/2016 4:11:02 PM,Good
|
||||
124,f3d49a1e-abca-4081-a6f3-1738cf37bf77,1,3/19/2016 10:21:02 PM,Good
|
||||
125,f4be8138-ee67-4ddc-bbd7-d0f5b752cbd0,1,3/19/2016 9:28:48 PM,Good
|
||||
126,f73354b1-5bb3-4f61-85a6-92b950d70481,Facebook:108531336210491,3/19/2016 2:55:43 PM,Good
|
||||
127,f96142e7-1ecc-4373-a7b7-351845fec052,1,3/19/2016 8:37:16 AM,Good
|
||||
128,fa30cf97-6af6-4b70-9ca4-44f75d446f41,1,3/19/2016 9:28:17 PM,Good
|
||||
129,fbb1a1e1-29e4-404b-aec7-fcca09592e72,1,3/19/2016 7:55:42 PM,Good
|
||||
130,fc677760-557c-40b8-b328-b45dcd833f22,Facebook:1047585061949223,3/19/2016 2:19:26 AM,Good
|
||||
131,fd31c6d9-3432-47ba-b6bd-392bae1029e3,1,3/19/2016 7:56:10 PM,Good
|
||||
132,fd7b0769-cdc6-4792-8805-1c282fe6194c,Facebook:1221443151217187,3/19/2016 6:05:32 PM,Good
|
||||
133,fff6151f-dfb7-400c-a112-1d0b1d401e41,1,3/19/2016 4:14:35 PM,Good
|
||||
134,003fc3f0-bd9b-4673-bd33-a343940a326d,1,3/20/2016 8:11:06 AM,Good
|
||||
135,14cb073b-f148-464e-96a1-6548208824f8,1,3/20/2016 4:10:57 PM,Good
|
||||
136,24c84e2d-ccd3-4e5d-af45-cf4361911c1d,1,3/20/2016 4:10:52 PM,Good
|
||||
137,2a203a61-9464-4682-8508-5b70baede7f7,1,3/20/2016 8:10:25 AM,Good
|
||||
138,322ecd58-f903-4e95-ae8f-cb6d690ea5ba,Facebook:203538940012375,3/20/2016 12:24:58 AM,Good
|
||||
139,3311f8ea-a8e4-4c3e-a0d2-2bd4943f6183,1,3/20/2016 4:11:09 PM,Good
|
||||
140,3677a316-2e44-4f4c-8294-e20684ec3e17,Facebook:203538940012375,3/20/2016 7:58:24 AM,Good
|
||||
141,38056345-39a2-474d-b5e4-18b978647470,Facebook:203538940012375,3/20/2016 7:59:38 AM,Good
|
||||
142,522b5c31-0750-4c61-8f68-42bcd6af123b,Facebook:203538940012375,3/20/2016 6:47:56 AM,Good
|
||||
143,69947721-da34-4c8f-af4b-54e4f7e69f00,Facebook:203538940012375,3/20/2016 8:46:23 AM,Good
|
||||
144,7628c48a-12bc-4fef-8b9f-9e2c32739d7c,1,3/20/2016 4:10:35 PM,Good
|
||||
145,79cad820-1ead-494b-be15-1a65bf342db8,Facebook:203538940012375,3/20/2016 7:37:35 AM,Good
|
||||
146,7a4f1137-a99a-48e7-bfa3-6a1037bcb449,1,3/20/2016 8:11:09 AM,Good
|
||||
147,7ddcffb7-1351-46ea-bd62-63232a541625,Twitter:19249356,3/20/2016 11:06:20 PM,Good
|
||||
148,81200e11-e4f8-40fc-a1cc-14848c388e46,1,3/20/2016 10:15:36 PM,Good
|
||||
149,814609ee-7b7a-4d32-9492-d2b2fddf49f8,Facebook:203538940012375,3/20/2016 5:41:23 PM,Good
|
||||
150,86e6e92b-a239-4e72-a8b2-802dafd1ff8a,Facebook:979553468780247,3/20/2016 10:54:20 PM,Good
|
||||
151,878e22d4-c451-4e0a-ac42-bf60b1ce9237,Facebook:203538940012375,3/20/2016 8:45:35 AM,Good
|
||||
152,8b8a8351-e0e6-489f-a3e3-8f0e2d6e7025,1,3/20/2016 2:00:38 AM,Good
|
||||
153,911a01c5-a5a4-4d12-988d-23fa44c88953,1,3/20/2016 8:10:23 AM,Good
|
||||
154,976a8901-e800-4c9d-a364-68fadf8f5ae5,1,3/20/2016 8:10:24 AM,Good
|
||||
155,98346ebc-96e7-4f8a-baf7-633a1e88344b,1,3/20/2016 8:10:50 AM,Good
|
||||
156,a0eb0031-c4af-4049-b225-798e3b08c8e1,Facebook:203538940012375,3/20/2016 6:07:02 AM,Good
|
||||
157,af3beb3a-4238-43e5-9a23-f6dc43e4ed10,Facebook:203538940012375,3/20/2016 8:45:50 AM,Good
|
||||
158,b0132ff6-8e92-4d7b-a6b3-0ceaef3f9afb,1,3/20/2016 12:03:00 AM,Good
|
||||
159,b1bdbefa-2833-4225-bde2-550041fbdaea,1,3/20/2016 4:11:17 PM,Good
|
||||
160,b58afdba-f60b-42ae-bca9-8c4d7f74c6be,1,3/20/2016 4:10:56 PM,Good
|
||||
161,b8a3500c-89df-47a0-9a22-381e5acf3575,1,3/20/2016 8:10:59 AM,Good
|
||||
162,b94dca78-6859-47f5-bef1-a7f679bbaf89,1,3/20/2016 4:10:47 PM,Good
|
||||
163,c05899dd-267b-453b-b244-69445f71e3ce,1,3/20/2016 8:10:28 AM,Good
|
||||
164,c08d750e-d7e5-4afc-9514-dfb258f01a94,1,3/20/2016 8:11:01 AM,Good
|
||||
165,c0dcda52-a310-4632-ab77-94e783a8b2f0,Facebook:203538940012375,3/20/2016 9:23:19 AM,Good
|
||||
166,c6e149b4-ff1e-45d5-bbed-26bf42c5c115,Facebook:203538940012375,3/20/2016 6:45:49 AM,Good
|
||||
167,d2f1b183-44e9-48fa-8c29-a8374c797490,1,3/20/2016 4:10:37 PM,Good
|
||||
168,d7455553-bce5-4207-ab91-94e650562f81,1,3/20/2016 8:10:44 AM,Good
|
||||
169,da877def-9408-4852-b71b-bf1b109c105c,1,3/20/2016 8:10:47 AM,Good
|
||||
170,e6f97648-f834-42a6-8451-53651bec0eed,Facebook:203538940012375,3/20/2016 8:43:53 AM,Good
|
||||
171,f064e7f8-8e35-48e7-aa66-cc936486f9a2,Facebook:10156612592435524,3/20/2016 2:47:04 PM,Good
|
||||
172,f09627ce-5efc-4977-8172-855545334c58,1,3/20/2016 4:10:39 PM,Good
|
||||
173,f21413fb-d216-47e4-8b72-bf2ea7a2e7ef,1,3/20/2016 4:11:23 PM,Good
|
||||
174,f50dad83-430e-4e19-a959-647ba75bdfb1,Facebook:203538940012375,3/20/2016 8:46:03 AM,Good
|
80
support/datainit/sql_data_init.sh
Normal file
80
support/datainit/sql_data_init.sh
Normal file
@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() { echo "Usage: sql_data_init.sh -s <SQL Server FQDN> -u <sql username> -p <sql password> -d <databaseName> " 1>&2; exit 1; }
|
||||
|
||||
declare sqlServerFQDN=""
|
||||
declare sqlServerUsername=""
|
||||
declare sqlPassword=""
|
||||
declare sqlDBName=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":s:u:p:d:" arg; do
|
||||
case "${arg}" in
|
||||
s)
|
||||
sqlServerFQDN=${OPTARG}
|
||||
;;
|
||||
u)
|
||||
sqlServerUsername=${OPTARG}
|
||||
;;
|
||||
p)
|
||||
sqlPassword=${OPTARG}
|
||||
;;
|
||||
d)
|
||||
sqlDBName=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [[ -z "$sqlServerFQDN" ]]; then
|
||||
echo "Enter FQDN to SQL Server:"
|
||||
read sqlServerFQDN
|
||||
[[ "${sqlServerFQDN:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$sqlServerUsername" ]]; then
|
||||
echo "Enter the SQL Server User name:"
|
||||
read sqlServerUsername
|
||||
[[ "${sqlServerUsername:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$sqlPassword" ]]; then
|
||||
echo "Enter the sql server password:"
|
||||
read sqlPassword
|
||||
[[ "${sqlPassword:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$sqlDBName" ]]; then
|
||||
echo "Enter the name of the SQL Server DB that was provisioned in shared infrastructure:"
|
||||
read sqlDBName
|
||||
fi
|
||||
|
||||
echo "Importing Devices"
|
||||
bcp Devices in ./data_load/Devices_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing factMLOutputData"
|
||||
bcp factMLOutputData in ./data_load/factMLOutputData_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing IOTHubDatas"
|
||||
bcp IOTHubDatas in ./data_load/IOTHubDatas_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing POIs"
|
||||
bcp POIs in ./data_load/POIs_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing TripPoints"
|
||||
bcp TripPoints in ./data_load/TripPoints_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing Trips"
|
||||
bcp Trips in ./data_load/Trips_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing UserProfiles"
|
||||
bcp UserProfiles in ./data_load/UserProfiles_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing POISource"
|
||||
bcp POISource in ./data_load/POISource_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
||||
|
||||
echo "Importing TripPointSource"
|
||||
bcp TripPointSource in ./data_load/TripPointSource_export.txt -S $sqlServerFQDN -U $sqlServerUsername -P $sqlPassword -d $sqlDBName -c -t ','
|
124
support/resources/KUSTO.md
Normal file
124
support/resources/KUSTO.md
Normal file
@ -0,0 +1,124 @@
|
||||
# Kusto tutorial with Log Analytics
|
||||
|
||||
This tutorial will guide you through the first steps with the Kusto query language in the context of the DevOps OpenHack.
|
||||
You create a graph that display how may trips have been completed by the simulator each half hour during the last 24 hours.
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
In order to walk through this tutorial, it is expected that you have created and configured an Azure Log Analytics workspace to collect the logs from your AKS cluster.
|
||||
|
||||
## Your first query
|
||||
|
||||
Open the query editor in your analytics workspace by selecting **Logs** in the log analytics menu and enter the following code:
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| search "simulator"
|
||||
```
|
||||
|
||||
Click the **Run** button.
|
||||
|
||||
This query uses **ContainerLog** as data source and searches for the entries that contain the word "simulator". The rows matching the criteria are returned.
|
||||
|
||||
Expand the first entry by clicking on the arrow on the left of the line. The key/value pairs will help understand the fields of each returned row.
|
||||
|
||||
Look more specifically at the following fields:
|
||||
- TimeGenerated\[UTC\]: This is the time at which the log entry has been generated
|
||||
- Image: This is the name of the container image that has generated the entry, copy the name of the image we will use it in the next step. It should be similar to this "openhackcj19acr.azurecr.io/devopsoh/simulator:latest"
|
||||
- LogEntry: The text that was written on the stdout of the container
|
||||
|
||||
## Filter the data
|
||||
|
||||
The command `where` allows to filter the data based on specific criteria like the generation time. The following query will apply a first filter on the data.
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
```
|
||||
|
||||
Let's now filter the content to only have the entries generated by the simulator container.
|
||||
Replace the query with the following and click **Run** :
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where Image contains "devopsoh/simulator:latest"
|
||||
```
|
||||
|
||||
When the simulator completes a trip an entry similar to the following is generated:
|
||||
```
|
||||
Trip Completed at : 11/01/2018 04:42:03.
|
||||
```
|
||||
|
||||
Let's update our query to select only those entries:
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where Image contains "devopsoh/simulator:latest"
|
||||
| where LogEntry contains "Trip Completed"
|
||||
```
|
||||
|
||||
Click **Run** to see the result.
|
||||
|
||||
The `where` clause also understands regular expressions(RE). REs can be used to extract a specific value from a log entry and write this value into an additional column using `extend`. More information on the use of `extend` is available on this page: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/get-started-queries?toc=/azure/azure-monitor/toc.json#project-and-extend-select-and-compute-columns
|
||||
|
||||
## Reduce the number of columns
|
||||
|
||||
Update the query to get only the information that interest us: time of generation, the log entry and the containerId.
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where Image contains "devopsoh/simulator:latest"
|
||||
| where LogEntry contains "Trip Completed"
|
||||
| project TimeGenerated, LogEntry, ContainerID
|
||||
```
|
||||
|
||||
The `project` command will display only the comma seperated list of column names in the result of the query.
|
||||
|
||||
Click **Run** to see the result.
|
||||
|
||||
## Count the number of entries per time slot
|
||||
|
||||
We will use the `summarize` command to perform the aggregation according to the time of generation.
|
||||
The `bin` function will round a value to its bin size; `bin(TimeGenerated, 1m)` round the TimeGenerated to the minute.
|
||||
Our query becomes:
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where Image contains "devopsoh/simulator:latest"
|
||||
| where LogEntry contains "Trip Completed"
|
||||
| project TimeGenerated, LogEntry, ContainerID
|
||||
| summarize count(LogEntry) by bin(TimeGenerated, 30m)
|
||||
```
|
||||
|
||||
Click **Run** to see the result.
|
||||
|
||||
## A picture worth thousand words
|
||||
|
||||
To represent the data on a graph we will use the `render` function and define the format, in our case we want a `timechart`
|
||||
|
||||
```kusto
|
||||
ContainerLog
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where Image contains "devopsoh/simulator:latest"
|
||||
| where LogEntry contains "Trip Completed"
|
||||
| project TimeGenerated, LogEntry, ContainerID
|
||||
| summarize count(LogEntry) by bin(TimeGenerated, 30m)
|
||||
| render timechart
|
||||
```
|
||||
|
||||
[Render operator](https://docs.microsoft.com/en-us/azure/kusto/query/renderoperator)
|
||||
[Creating Charts and Diagrams From Log Analytics](https://docs.microsoft.com/en-us/azure/log-analytics/query-language/charts?toc=/azure/azure-monitor/toc.json)
|
||||
|
||||
Click **Run** to render the graph.
|
||||
|
||||
## Reference documents
|
||||
|
||||
- Getting stated with log analytics portal: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/get-started-analytics-portal
|
||||
- Getting started with query: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/get-started-analytics-portal
|
||||
- String operations with Kusto: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/string-operations
|
||||
- Search queries in Log Analytics: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/search-queries
|
||||
- Add or select new column in a query: https://docs.microsoft.com/en-us/azure/log-analytics/query-language/get-started-queries?toc=/azure/azure-monitor/toc.json#project-and-extend-select-and-compute-columns
|
140
support/resources/MyDrivingTest.jmx
Normal file
140
support/resources/MyDrivingTest.jmx
Normal file
@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1 r1853635">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="MyDriving Load Test" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="UserJavaUri" elementType="Argument">
|
||||
<stringProp name="Argument.name">UserJavaUri</stringProp>
|
||||
<stringProp name="Argument.value">${__BeanShell(System.getenv("UserJavaUri"))}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="UserProfileUri" elementType="Argument">
|
||||
<stringProp name="Argument.name">UserProfileUri</stringProp>
|
||||
<stringProp name="Argument.value">${__BeanShell(System.getenv("UserProfileUri"))}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="TripsURI" elementType="Argument">
|
||||
<stringProp name="Argument.name">TripsURI</stringProp>
|
||||
<stringProp name="Argument.value">${__BeanShell(System.getenv("TripsURI"))}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="PoiURI" elementType="Argument">
|
||||
<stringProp name="Argument.name">PoiURI</stringProp>
|
||||
<stringProp name="Argument.value">${__BeanShell(System.getenv("PoiURI"))}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</Arguments>
|
||||
<hashTree/>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<intProp name="LoopController.loops">-1</intProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">5</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">10</stringProp>
|
||||
<boolProp name="ThreadGroup.scheduler">true</boolProp>
|
||||
<stringProp name="ThreadGroup.duration">120</stringProp>
|
||||
<stringProp name="ThreadGroup.delay">5</stringProp>
|
||||
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POI Healthcheck" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value"></stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">${PoiURI}</stringProp>
|
||||
<stringProp name="HTTPSampler.port"></stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">https</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/api/healthcheck/poi/</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Trips Healthcheck" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">${TripsURI}</stringProp>
|
||||
<stringProp name="HTTPSampler.port"></stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">https</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/api/healthcheck/trips</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="UserJava Healthcheck" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">${UserJavaUri}</stringProp>
|
||||
<stringProp name="HTTPSampler.port"></stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">https</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/api/healthcheck/user-java</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="UserProfile Healthcheck" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">${UserProfileUri}</stringProp>
|
||||
<stringProp name="HTTPSampler.port"></stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">https</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/api/healthcheck/user</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
25
support/resources/generic_endpoint.sh
Normal file
25
support/resources/generic_endpoint.sh
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set AZURE_DEVOPS_EXT_PAT with your PAT befor running this script
|
||||
# export export AZURE_DEVOPS_EXT_PAT="YourPat"
|
||||
|
||||
# ./generic_endpoint.sh AdoOrganization AdoProject SvcEndpointName SvcEndpointUrl
|
||||
|
||||
AZURE_DEVOPS_ORGANIZATION=$1 # $(System.CollectionUri)
|
||||
AZURE_DEVOPS_PROJECT=$2 # $(System.TeamProject)
|
||||
SVC_ENDPOINT_NAME=$3
|
||||
SVC_ENDPOINT_URL=$4
|
||||
|
||||
az devops configure --defaults organization="${AZURE_DEVOPS_ORGANIZATION}" project="${AZURE_DEVOPS_PROJECT}"
|
||||
|
||||
id=$(az devops service-endpoint list --query "[?name == '${SVC_ENDPOINT_NAME}'].id | join(', ', @)" --output tsv)
|
||||
if [[ ${#id} == 0 ]]; then
|
||||
payload=$(cat generic_endpoint_template.json)
|
||||
echo $payload | jq -c -r '.name = "'${SVC_ENDPOINT_NAME}'" | .url = "'${SVC_ENDPOINT_URL}'"' > _endpoint.temp.json
|
||||
id=$(az devops service-endpoint create --service-endpoint-configuration _endpoint.temp.json --output tsv --query id)
|
||||
rm -f _endpoint.temp.json
|
||||
az devops service-endpoint update --id ${id} --enable-for-all true > /dev/null
|
||||
echo "${SVC_ENDPOINT_NAME} service endpoint creadted! id: ${id}"
|
||||
else
|
||||
echo "${SVC_ENDPOINT_NAME} service endpoint already exists!"
|
||||
fi
|
22
support/resources/generic_endpoint_template.json
Normal file
22
support/resources/generic_endpoint_template.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"administratorsGroup": null,
|
||||
"authorization": {
|
||||
"scheme": "UsernamePassword",
|
||||
"parameters": {
|
||||
"username": "",
|
||||
"password": ""
|
||||
}
|
||||
},
|
||||
"createdBy": null,
|
||||
"data": {},
|
||||
"description": "",
|
||||
"groupScopeId": null,
|
||||
"name": "NAME",
|
||||
"operationStatus": null,
|
||||
"readersGroup": null,
|
||||
"serviceEndpointProjectReferences": [],
|
||||
"type": "generic",
|
||||
"url": "URL",
|
||||
"isShared": false,
|
||||
"owner": "library"
|
||||
}
|
59
support/resources/healthcheck_polling.sh
Normal file
59
support/resources/healthcheck_polling.sh
Normal file
@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare -i duration=5
|
||||
declare endpoint
|
||||
declare key
|
||||
declare value
|
||||
|
||||
usage() {
|
||||
cat <<END
|
||||
healthcheck.sh endpoint key value
|
||||
|
||||
Report the health status of the endpoint. Exit 0 then OK.
|
||||
END
|
||||
}
|
||||
|
||||
if [[ $1 ]]; then
|
||||
endpoint=$1
|
||||
else
|
||||
echo "Please specify the endpoint to scan"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $2 ]]; then
|
||||
key=$2
|
||||
else
|
||||
echo "Please specify the key that has to be queried"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $3 ]]; then
|
||||
value=$3
|
||||
else
|
||||
echo "Please specify the value that has to be expected"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
query() {
|
||||
local endpoint=$1
|
||||
local key=$2
|
||||
|
||||
result=$(curl --max-time 5 --silent --location "${endpoint}")
|
||||
|
||||
if jq -e . >/dev/null 2>&1 <<<"${result}"; then
|
||||
echo "${result}" | jq -c -r '.'"${key}"''
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ true ]]; do
|
||||
result=$(query "${endpoint}" "${key}")
|
||||
|
||||
if [[ "${result}" == "${value}" ]]; then
|
||||
echo true
|
||||
exit 0
|
||||
fi
|
||||
sleep ${duration}
|
||||
done
|
64
support/resources/polling.sh
Normal file
64
support/resources/polling.sh
Normal file
@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare -i duration=1
|
||||
declare hasUrl=""
|
||||
declare endpoint
|
||||
|
||||
usage() {
|
||||
cat <<END
|
||||
polling.sh [-i] [-h] endpoint
|
||||
|
||||
Report the health status of the endpoint
|
||||
-i: include Uri for the format
|
||||
-h: help
|
||||
END
|
||||
}
|
||||
|
||||
while getopts "ih" opt; do
|
||||
case $opt in
|
||||
i)
|
||||
hasUrl=true
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
echo "Unknown option: -${OPTARG}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND -1))
|
||||
|
||||
if [[ $1 ]]; then
|
||||
endpoint=$1
|
||||
else
|
||||
echo "Please specify the endpoint."
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
healthcheck() {
|
||||
declare url=$1
|
||||
result=$(curl --silent --location --head --output /dev/null --write-out "%{http_code}" "${url}")
|
||||
echo $result
|
||||
}
|
||||
|
||||
while [[ true ]]; do
|
||||
result=`healthcheck ${endpoint}`
|
||||
declare status
|
||||
if [[ -z ${result} ]]; then
|
||||
status="N/A"
|
||||
else
|
||||
status=${result}
|
||||
fi
|
||||
timestamp=$(date "+%Y%m%d-%H%M%S")
|
||||
if [[ -z ${hasUrl} ]]; then
|
||||
echo "${timestamp} | ${status} "
|
||||
else
|
||||
echo "${timestamp} | ${status} | ${endpoint} "
|
||||
fi
|
||||
sleep ${duration}
|
||||
done
|
60
support/resources/send_msg.sh
Normal file
60
support/resources/send_msg.sh
Normal file
@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() { echo "Usage: send_msg -e <recipientEmail> -c <chatConnectionString> -q <chatMessageQueue> -m <message>" 1>&2; exit 1; }
|
||||
|
||||
declare recipientEmail=""
|
||||
declare chatConnectionString=""
|
||||
declare chatMessageQueue=""
|
||||
declare message=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":e:c:q:m:" arg; do
|
||||
case "${arg}" in
|
||||
e)
|
||||
recipientEmail=${OPTARG}
|
||||
;;
|
||||
c)
|
||||
chatConnectionString=${OPTARG}
|
||||
;;
|
||||
q)
|
||||
chatMessageQueue=${OPTARG}
|
||||
;;
|
||||
m)
|
||||
message=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [[ -z "$recipientEmail" ]]; then
|
||||
echo "recipientEmail was not set properly"
|
||||
read recipientEmail
|
||||
fi
|
||||
|
||||
if [[ -z "$chatConnectionString" ]]; then
|
||||
echo "chatConnectionString was not set properly"
|
||||
read chatConnectionString
|
||||
fi
|
||||
|
||||
if [[ -z "$chatMessageQueue" ]]; then
|
||||
echo "chatMessageQueue was not set properly"
|
||||
read chatMessageQueue
|
||||
fi
|
||||
|
||||
if [[ -z "$message" ]]; then
|
||||
echo "message was not set properly"
|
||||
read message
|
||||
fi
|
||||
|
||||
cd /home/azureuser/openhack-devops-proctor/provision-team/svcbusclient
|
||||
|
||||
# Restore the ServiceBus Package
|
||||
dotnet add package Microsoft.Azure.ServiceBus --version 3.1.0
|
||||
|
||||
# build the servicebus client app
|
||||
dotnet build
|
||||
|
||||
# send the message to servicebus
|
||||
dotnet run $chatConnectionString $chatMessageQueue $recipientEmail $message
|
85
support/resources/service_check.sh
Normal file
85
support/resources/service_check.sh
Normal file
@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
usage() { echo "Usage: service_check.sh -d <dns host Url> -n <teamName> " 1>&2; exit 1; }
|
||||
|
||||
declare dnsUrl=""
|
||||
declare teamName=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":d:n:" arg; do
|
||||
case "${arg}" in
|
||||
d)
|
||||
dnsUrl=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
teamName=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$dnsUrl" ]]; then
|
||||
echo "Public DNS address where the API will be hosted behind."
|
||||
echo "Enter public DNS name."
|
||||
read dnsUrl
|
||||
[[ "${dnsUrl:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$teamName" ]]; then
|
||||
echo "Enter a team name to be used in app provisioning:"
|
||||
read teamName
|
||||
fi
|
||||
|
||||
echo "Checking services for ([X] = PASSED):"
|
||||
echo "Team Name:" $teamName
|
||||
echo -e "DNS Url:" $dnsUrl"\n"
|
||||
|
||||
poi_URL=$dnsUrl"/api/healthcheck/poi"
|
||||
user_URL=$dnsUrl"/api/healthcheck/user"
|
||||
trips_URL=$dnsUrl"/api/healthcheck/trips"
|
||||
user_java_URL=$dnsUrl"/api/healthcheck/user-java"
|
||||
|
||||
echo -e "Checking POI:\t"$poi_URL
|
||||
echo -e "Checking USER:\t"$user_URL
|
||||
echo -e "Checking TRIPS:\t"$trips_URL
|
||||
echo -e "Checking USER JAVA:\t"$user_java_URL"\n"
|
||||
|
||||
status_code_poi=`curl -sL -w "%{http_code}\\n" "$poi_URL" -o /dev/null`
|
||||
|
||||
if [[ "$status_code_poi" == "200" ]]; then
|
||||
echo "poi [X]"
|
||||
else
|
||||
echo "poi [ ]"
|
||||
fi
|
||||
|
||||
status_code_user=`curl -sL -w "%{http_code}\\n" "$user_URL" -o /dev/null`
|
||||
|
||||
if [[ "$status_code_user" == "200" ]]; then
|
||||
echo "user [X]"
|
||||
else
|
||||
echo "user [ ]"
|
||||
fi
|
||||
|
||||
status_code_trips=`curl -sL -w "%{http_code}\\n" "$trips_URL" -o /dev/null`
|
||||
|
||||
if [[ "$status_code_trips" == "200" ]]; then
|
||||
echo "trips [X]"
|
||||
else
|
||||
echo "trips [ ]"
|
||||
fi
|
||||
|
||||
status_code_user_java=`curl -sL -w "%{http_code}\\n" "$user_java_URL" -o /dev/null`
|
||||
|
||||
if [[ "$status_code_user_java" == "200" ]]; then
|
||||
echo "user-java [X]"
|
||||
else
|
||||
echo "user-java [ ]"
|
||||
fi
|
||||
|
||||
if [[ "$status_code_poi" == "200" ]] && [[ "$status_code_user" == "200" ]] && [[ "$status_code_trips" == "200" ]] && [[ "$status_code_user_java" == "200" ]]; then
|
||||
echo "All checks passed"
|
||||
fi
|
129
support/resources/validate-deployment.ps1
Normal file
129
support/resources/validate-deployment.ps1
Normal file
@ -0,0 +1,129 @@
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
This script can be used to check the status of a classroom after is has been started in the Cloud Sandbox.
|
||||
|
||||
This script has specficially been authored to check the lab microsoft-open-hack-devops and will not currently validate any other OpenHack labs.
|
||||
|
||||
.DESCRIPTION
|
||||
To use this script, you will need to navigate to a classroom in the Cloud Sandbox and enter the lab view.
|
||||
|
||||
From the lab view, click the List Credentials button, and then export the CSV.
|
||||
|
||||
This script will take the path of that script as in input and use the credentials to enumerate all of the subscriptions within it.
|
||||
|
||||
.EXAMPLE
|
||||
./validate-deployment.ps1 -LabCredentialsFilePath $env:HOMEPATH\Downloads\credentials.csv
|
||||
|
||||
.NOTES
|
||||
This script should only be run at one hour after you have initiated the lab. Running it prior to that will certainly lead to results which lead you to believe the lab has not provisioned successfully, when in fact it is probably just still spinning up.
|
||||
|
||||
.LINK
|
||||
https://github.com/Azure-Samples/openhack-devops-proctor/
|
||||
|
||||
#>
|
||||
|
||||
Param (
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]
|
||||
$LabCredentialsFilePath = "credentials.csv",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[String]
|
||||
$OutputFilePath = "classroom_checkresults.csv",
|
||||
|
||||
[switch]
|
||||
$Force
|
||||
)
|
||||
|
||||
if (-Not (Test-Path $LabCredentialsFilePath -PathType Leaf)) {
|
||||
Write-Error -Message "Unable to find CSV at the path provided." -Category InvalidData
|
||||
}
|
||||
|
||||
$InputFile = @(Import-Csv -Path $LabCredentialsFilePath -Header "PortalUsername","PortalPassword","AzureSubscriptionId","AzureDisplayName","AzureUsername","AzurePassword" | Where-Object AzureUserName -like "hacker*" | Sort-Object AzureSubscriptionId -Unique)
|
||||
|
||||
if (Test-Path $OutputFilePath -PathType Leaf) {
|
||||
if ($Force) {
|
||||
Remove-Item -Path $OutputFilePath
|
||||
} else {
|
||||
$_ = Read-Host "Found previous output. Would you like to delete it? (y/n)?"
|
||||
|
||||
if ($_.ToLower() -eq "y") {
|
||||
Remove-Item -Path $OutputFilePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Storing validation results at $OutputFilePath" -ForegroundColor Green
|
||||
|
||||
Add-Content -Path $OutputFilePath -Value '"SiteFound","POIFound","TripsFound","UserFound","UserJavaFound","TripViewerUrl","AzureUsername","AzurePassword","SubscriptionId","TenantURL"'
|
||||
|
||||
for ($i = 0; $i -lt $InputFile.Count; $i++) {
|
||||
$_ = $InputFile[$i]
|
||||
|
||||
if ($_.AzureUsername -eq "Azure UserName" -and $_.AzurePassword -eq "Azure Password") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$PortalUsername = $_.PortalUsername
|
||||
$PortalPassword = $_.PortalPassword
|
||||
$AzureUsername = $_.AzureUsername
|
||||
$AzurePassword = $_.AzurePassword
|
||||
$AzureSubscriptionId = $_.AzureSubscriptionId
|
||||
$AzureDisplayName = $_.AzureDisplayName
|
||||
|
||||
$AzureSecurePassword = ConvertTo-SecureString $AzurePassword -AsPlainText -Force
|
||||
$Credential = New-Object System.Management.Automation.PSCredential ($AzureUsername, $AzureSecurePassword)
|
||||
$TenantDomain = $AzureUsername.Split("@")[1]
|
||||
$TenantUrl = "https://portal.azure.com/$TenantDomain"
|
||||
|
||||
Write-Host "Processing record for $AzureUsername" -ForegroundColor Yellow
|
||||
|
||||
$Account = Connect-AzAccount -Credential $Credential -Subscription $AzureSubscriptionId
|
||||
|
||||
$ResourceGroup = Get-AzResourceGroup | Where-Object ResourceGroupName -like "openhack*" | Select-Object -first 1
|
||||
$ResourceGroupName = $ResourceGroup.ResourceGroupName
|
||||
$TeamName = $ResourceGroupName -Replace ".{2}$"
|
||||
|
||||
$RowToAppend = '"True",'
|
||||
|
||||
$_poi = Get-AzWebApp -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq "$($TeamName)poi" }
|
||||
$_trips = Get-AzWebApp -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq "$($TeamName)trips" }
|
||||
$_userprofile = Get-AzWebApp -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq "$($TeamName)userprofile" }
|
||||
$_userjava = Get-AzWebApp -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq "$($TeamName)userjava" }
|
||||
$_tripviewer = Get-AzWebApp -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq "$($TeamName)tripviewer" }
|
||||
|
||||
$_status = Invoke-WebRequest "http://$($_poi.DefaultHostName)/api/healthcheck/poi" | % {$_.StatusCode}
|
||||
if ($_status -eq 200) {
|
||||
$RowToAppend += '"True",'
|
||||
} else {
|
||||
$RowToAppend += '"False",'
|
||||
}
|
||||
|
||||
$_status = Invoke-WebRequest "http://$($_trips.DefaultHostName)/api/healthcheck/trips" | % {$_.StatusCode}
|
||||
if ($_status -eq 200) {
|
||||
$RowToAppend += '"True",'
|
||||
} else {
|
||||
$RowToAppend += '"False",'
|
||||
}
|
||||
|
||||
$_status = Invoke-WebRequest "http://$($_userprofile.DefaultHostName)/api/healthcheck/user" | % {$_.StatusCode}
|
||||
if ($_status -eq 200) {
|
||||
$RowToAppend += '"True",'
|
||||
} else {
|
||||
$RowToAppend += '"False",'
|
||||
}
|
||||
|
||||
$_status = Invoke-WebRequest "http://$($_userjava.DefaultHostName)/api/healthcheck/user-java" | % {$_.StatusCode}
|
||||
if ($_status -eq 200) {
|
||||
$RowToAppend += '"True",'
|
||||
} else {
|
||||
$RowToAppend += '"False",'
|
||||
}
|
||||
|
||||
$RowToAppend += "`"http://$($_tripviewer.DefaultHostName)`",`"$PortalUsername`",`"$PortalPassword`",`"$AzureSubscriptionId`",`"$TenantUrl`""
|
||||
|
||||
Add-Content -Path $OutputFilePath -Value $RowToAppend
|
||||
|
||||
Write-Host "Done for $AzureUsername"
|
||||
}
|
112
support/resources/validate-deployment.sh
Normal file
112
support/resources/validate-deployment.sh
Normal file
@ -0,0 +1,112 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script verifies the successfull deployment of the resources needed for the DevOps OpenHack.
|
||||
# You need to provide the CSV file with all the credentials of the Azure subscriptions from the classroom management portal and a private / public SSH keypair that will be used to access the provisioning VMs
|
||||
# The error log file is where will be logged the informations regarding the failed deployments. If not provided, it defaults to error.log.
|
||||
#
|
||||
# EXAMPLE
|
||||
# ./validate-deployment.sh ./credentials.csv
|
||||
# ./validate-deployment.sh ./credentials.csv --force
|
||||
|
||||
OLD_IFS=$IFS
|
||||
CREDENTIALS_FILE_PATH=$1
|
||||
FORCE_OVERWRITE=$2
|
||||
RESULTS_FILE_PATH="./classcheckresults.csv"
|
||||
IFS=','
|
||||
|
||||
[ ! -f $CREDENTIALS_FILE_PATH ] && { echo "$CREDENTIALS_FILE_PATH file not found"; exit 99; }
|
||||
|
||||
[ -f $RESULTS_FILE_PATH ] && {
|
||||
[ -z $FORCE_OVERWRITE ] && {
|
||||
echo "Found previous output ($RESULTS_FILE_PATH). Would you like to delete it?"
|
||||
select yn in "Yes" "No"; do
|
||||
case $yn in
|
||||
Yes ) rm $RESULTS_FILE_PATH; break;;
|
||||
No ) break;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
[ ! -z $FORCE_OVERWRITE ] && {
|
||||
rm $RESULTS_FILE_PATH
|
||||
}
|
||||
}
|
||||
|
||||
echo "Storing validation results at $RESULTS_FILE_PATH"
|
||||
|
||||
echo '"SiteFound","POIFound","TripsFound","UserFound","UserJavaFound","TripViewerUrl","AzureUsername","AzurePassword","SubscriptionId","TenantURL"' >> $RESULTS_FILE_PATH
|
||||
|
||||
while read PortalUsername PortalPassword AzureSubscriptionId AzureDisplayName AzureUsername AzurePassword
|
||||
do
|
||||
if [[ $PortalUsername = *Portal* ]]
|
||||
then
|
||||
echo "This is the header, skipping..."
|
||||
elif [[ $AzureUserName = *hacker* ]]
|
||||
then
|
||||
echo "This is a hacker user, skipping..."
|
||||
else
|
||||
echo "PortalUsername $PortalUsername"
|
||||
echo "PortalPassword $PortalPassword"
|
||||
echo "AzureSubscriptionId $AzureSubscriptionId"
|
||||
echo "AzureDisplayName $AzureDisplayName"
|
||||
echo "AzureUsername $AzureUsername"
|
||||
echo "AzurePassword $AzurePassword"
|
||||
|
||||
az login -u $AzureUsername -p $AzurePassword --output none
|
||||
|
||||
TENANT_URL="https://portal.azure.com/"
|
||||
TENANT_URL+=`echo "$AzureUsername" | awk -F"@" '{print $2}'`
|
||||
|
||||
RESOURCE_GROUP_NAME=`az group list --query "[?starts_with(name,'openhack')]|[0]" | jq -r '.name'`
|
||||
|
||||
TEAM_NAME=${RESOURCE_GROUP_NAME%??}
|
||||
|
||||
ROW_TO_APPEND="\"True\","
|
||||
|
||||
FQDN_POI=`az webapp show --resource-group "$RESOURCE_GROUP_NAME" --name "${TEAM_NAME}poi" --query "[].{hostName:defaultHostName}|[0]" --output tsv`
|
||||
FQDN_TRIPS=`az webapp list --resource-group "$RESOURCE_GROUP_NAME" --name "${TEAM_NAME}trips" --query "[].{hostName:defaultHostName}|[0]" --output tsv`
|
||||
FQDN_USER_JAVA=`az webapp list --resource-group "$RESOURCE_GROUP_NAME" --name "${TEAM_NAME}userjava" --query "[].{hostName:defaultHostName}|[0]" --output tsv`
|
||||
FQDN_USER_PROFILE=`az webapp list --resource-group "$RESOURCE_GROUP_NAME" --name "${TEAM_NAME}userprofile" --query "[].{hostName:defaultHostName}|[0]" --output tsv`
|
||||
|
||||
FQDN_TRIP_VIEWER=`az webapp list --resource-group "$RESOURCE_GROUP_NAME" --name "${TEAM_NAME}tripviewer" --query "[].{hostName:defaultHostName}|[0]" --output tsv`
|
||||
|
||||
STATUS=$(curl --write-out %{http_code} --silent --output /dev/null $FQDN_POI/api/healthcheck/poi)
|
||||
if [ $STATUS -eq 200 ]
|
||||
then
|
||||
ROW_TO_APPEND+="\"True\","
|
||||
else
|
||||
ROW_TO_APPEND+="\"False\","
|
||||
fi
|
||||
|
||||
STATUS=$(curl --write-out %{http_code} --silent --output /dev/null $FQDN_TRIPS/api/healthcheck/trips)
|
||||
if [ $STATUS -eq 200 ]
|
||||
then
|
||||
ROW_TO_APPEND+="\"True\","
|
||||
else
|
||||
ROW_TO_APPEND+="\"False\","
|
||||
fi
|
||||
|
||||
STATUS=$(curl --write-out %{http_code} --silent --output /dev/null $FQDN_USER_PROFILE/api/healthcheck/user)
|
||||
if [ $STATUS -eq 200 ]
|
||||
then
|
||||
ROW_TO_APPEND+="\"True\","
|
||||
else
|
||||
ROW_TO_APPEND+="\"False\","
|
||||
fi
|
||||
|
||||
STATUS=$(curl --write-out %{http_code} --silent --output /dev/null $FQDN_USER_JAVA/api/healthcheck/user-java)
|
||||
if [ $STATUS -eq 200 ]
|
||||
then
|
||||
ROW_TO_APPEND+="\"True\","
|
||||
else
|
||||
ROW_TO_APPEND+="\"False\","
|
||||
fi
|
||||
|
||||
ROW_TO_APPEND+="\"$FQDN_TRIP_VIEWER\",\"$PortalUsername\",\"$PortalPassword\",\"$AzureSubscriptionId\",\"$TENANT_URL\""
|
||||
|
||||
echo $ROW_TO_APPEND >> $RESULTS_FILE_PATH
|
||||
|
||||
echo "Done for $AzureUsername"
|
||||
fi
|
||||
|
||||
done < $CREDENTIALS_FILE_PATH
|
||||
IFS=$OLD_IFS
|
10
support/simulator/.dockerignore
Normal file
10
support/simulator/.dockerignore
Normal file
@ -0,0 +1,10 @@
|
||||
.dockerignore
|
||||
.env
|
||||
.git
|
||||
.gitignore
|
||||
.vs
|
||||
.vscode
|
||||
docker-compose.yml
|
||||
docker-compose.*.yml
|
||||
*/bin
|
||||
*/obj
|
5
support/simulator/DeviceSim/App.config
Normal file
5
support/simulator/DeviceSim/App.config
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
</appSettings>
|
||||
</configuration>
|
258
support/simulator/DeviceSim/Controllers/ApiTripController.cs
Normal file
258
support/simulator/DeviceSim/Controllers/ApiTripController.cs
Normal file
@ -0,0 +1,258 @@
|
||||
using DeviceSim.Helpers;
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Stores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DeviceSim.Controllers
|
||||
{
|
||||
public class ApiTripController : BaseTripController
|
||||
{
|
||||
private Trip CurrentTrip;
|
||||
private List<TripPoint> CurrentTripPoints;
|
||||
private TripStore tripStore;
|
||||
private TripPointStore tripPointStore;
|
||||
private PoiStore poiStore;
|
||||
private UserStore userStore;
|
||||
private string userApiEndPoint;
|
||||
private string poiApiEndPoint;
|
||||
private string tripsApiEndPoint;
|
||||
private DateTime dateTime;
|
||||
|
||||
public ApiTripController(DBConnectionInfo dBConnectionInfo, string UserApiEndPoint,string PoiApiEndPoint, string TripsApiEndPoint ) : base(dBConnectionInfo)
|
||||
{
|
||||
userApiEndPoint = UserApiEndPoint;
|
||||
poiApiEndPoint = PoiApiEndPoint;
|
||||
tripsApiEndPoint = TripsApiEndPoint;
|
||||
tripStore = new TripStore(tripsApiEndPoint);
|
||||
tripPointStore = new TripPointStore(tripsApiEndPoint);
|
||||
poiStore = new PoiStore(poiApiEndPoint);
|
||||
userStore = new UserStore(userApiEndPoint);
|
||||
}
|
||||
|
||||
public async Task CreateTrip()
|
||||
{
|
||||
dateTime = DateTime.UtcNow;
|
||||
|
||||
CurrentTrip = new Trip
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
UserId = "Hacker 1",
|
||||
Name = $"API-Trip {DateTime.Now}",
|
||||
RecordedTimeStamp = dateTime.AddTicks(-1 * dateTime.Ticks % 10000),
|
||||
EndTimeStamp = dateTime.AddTicks(-1 * dateTime.Ticks % 10000),
|
||||
UpdatedAt = dateTime.AddTicks(-1 * dateTime.Ticks % 10000),
|
||||
Distance = 5.95,
|
||||
Rating = 90,
|
||||
Created = dateTime.AddTicks(-1 * dateTime.Ticks % 10000)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
CurrentTrip = await tripStore.CreateItemAsync(CurrentTrip);
|
||||
|
||||
await CreateTripPoints();
|
||||
|
||||
await CreatePois();
|
||||
|
||||
await UpdateUserProfile();
|
||||
|
||||
await UpdateTrip();
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new Exception($"Trip was not Recorded Successfully: \n Trip Name : {CurrentTrip.Name} \n Trip Guid: {CurrentTrip.Id}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task CreateTripPoints()
|
||||
{
|
||||
try
|
||||
{
|
||||
CurrentTripPoints = new List<TripPoint>();
|
||||
DateTime dateTime = DateTime.UtcNow;
|
||||
Vin v = new Vin() { String = string.Empty, Valid = false };
|
||||
|
||||
foreach (var tps in TripPointSourceInfo)
|
||||
{
|
||||
TripPoint _tripPoint = new TripPoint()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
TripId = new Guid(CurrentTrip.Id),
|
||||
Latitude = Convert.ToDouble(tps.Lat),
|
||||
Longitude = Convert.ToDouble(tps.Lon),
|
||||
Speed = Convert.ToDouble(tps.Speed),
|
||||
RecordedTimeStamp = Convert.ToDateTime(tps.Recordedtimestamp),
|
||||
Sequence = Convert.ToInt32(tps.Sequence),
|
||||
Rpm = Convert.ToDouble(tps.Enginerpm),
|
||||
ShortTermFuelBank = Convert.ToDouble(tps.Shorttermfuelbank),
|
||||
LongTermFuelBank = Convert.ToDouble(tps.Longtermfuelbank),
|
||||
ThrottlePosition = Convert.ToDouble(tps.Throttleposition),
|
||||
RelativeThrottlePosition = Convert.ToDouble(tps.Relativethrottleposition),
|
||||
Runtime = Convert.ToDouble(tps.Runtime),
|
||||
DistanceWithMalfunctionLight = Convert.ToDouble(tps.Distancewithmil),
|
||||
EngineLoad = Convert.ToDouble(tps.Engineload),
|
||||
//MassFlowRate = Convert.ToDouble(tps.Mafflowrate),
|
||||
EngineFuelRate = Convert.ToDouble(tps.Enginefuelrate),
|
||||
Vin = v,
|
||||
CreatedAt = dateTime.AddTicks(-1 * dateTime.Ticks % 10000),
|
||||
UpdatedAt = dateTime.AddTicks(-1 * dateTime.Ticks % 10000)
|
||||
};
|
||||
CurrentTripPoints.Add(_tripPoint);
|
||||
}
|
||||
|
||||
//Update Time Stamps to current date and times before sending to IOT Hub
|
||||
UpdateTripPointTimeStamps(CurrentTrip);
|
||||
foreach (TripPoint tripPoint in CurrentTripPoints)
|
||||
{
|
||||
try
|
||||
{
|
||||
await tripPointStore.CreateItemAsync(tripPoint);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new Exception($"Could not update Trip Time Stamps from Samples at {DateTime.Now.ToString()}.");
|
||||
}
|
||||
|
||||
//Console.WriteLine($"Processing Sequence No: {tripPoint.Sequence} on Thread : {Thread.CurrentThread.ManagedThreadId}");
|
||||
}
|
||||
|
||||
//Parallel.ForEach(CurrentTripPoints, tripPoint =>
|
||||
//{
|
||||
// tripPointStore.CreateItemAsync(tripPoint);
|
||||
// Console.WriteLine($"Processing Sequence No: {tripPoint.Sequence} on Thread : {Thread.CurrentThread.ManagedThreadId}");
|
||||
|
||||
//});
|
||||
|
||||
//Console.WriteLine("TripPoint Processing Completed");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Could not create/update Trip Points. For more detail see: {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTripPointTimeStamps(Trip trip)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Sort Trip Points By Sequence Number
|
||||
CurrentTripPoints = CurrentTripPoints.OrderBy(p => p.Sequence).ToList();
|
||||
|
||||
List<timeInfo> timeToAdd = new List<timeInfo>();
|
||||
System.TimeSpan tDiff;
|
||||
|
||||
//Create a Variable to Track the Time Range as it Changes
|
||||
System.DateTime runningTime = CurrentTrip.RecordedTimeStamp;
|
||||
|
||||
//Calculate the Difference in time between Each Sequence Item
|
||||
for (int currentTripPoint = (CurrentTripPoints.Count - 1); currentTripPoint > -1; currentTripPoint--)
|
||||
{
|
||||
if (currentTripPoint > 0)
|
||||
{
|
||||
tDiff = CurrentTripPoints.ElementAt(currentTripPoint).RecordedTimeStamp
|
||||
- CurrentTripPoints.ElementAt(currentTripPoint - 1).RecordedTimeStamp;
|
||||
timeToAdd.Add(new timeInfo() { evtSeq = CurrentTripPoints.ElementAt(currentTripPoint).Sequence, tSpan = tDiff });
|
||||
}
|
||||
}
|
||||
|
||||
//Sort List in order to Add time to Trip Points
|
||||
timeToAdd = timeToAdd.OrderBy(s => s.evtSeq).ToList();
|
||||
//Update Trip Points
|
||||
|
||||
for (int currentTripPoint = 1, timeToAddCollIdx = 0; currentTripPoint < CurrentTripPoints.Count; currentTripPoint++, timeToAddCollIdx++)
|
||||
{
|
||||
runningTime = runningTime.Add(timeToAdd[timeToAddCollIdx].tSpan);
|
||||
CurrentTripPoints.ElementAt(currentTripPoint).RecordedTimeStamp = runningTime;
|
||||
}
|
||||
|
||||
// Update Initial Trip Point
|
||||
CurrentTripPoints.ElementAt(0).RecordedTimeStamp = CurrentTrip.RecordedTimeStamp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Could not update Trip Time Stamps from Samples. for more info see:{ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreatePois()
|
||||
{
|
||||
//CurrentPois = new List<Poi>();
|
||||
foreach (var poi in TripPOIsource)
|
||||
{
|
||||
try
|
||||
{
|
||||
dateTime = DateTime.Now;
|
||||
await poiStore.CreateItemAsync(new Poi
|
||||
{
|
||||
TripId = new Guid(CurrentTrip.Id),
|
||||
Latitude = poi.Latitude,
|
||||
Longitude = poi.Longitude,
|
||||
PoiType = poi.Poitype,
|
||||
Deleted = false,
|
||||
Id = Guid.NewGuid(),
|
||||
Timestamp = dateTime.AddTicks(-1 * dateTime.Ticks % 10000)
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine($"POI Creation Failure : {DateTime.Now.ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
CurrentTrip.HardStops = TripPOIsource.Where(p => p.Poitype == 2).Count();
|
||||
CurrentTrip.HardAccelerations = TripPOIsource.Where(p => p.Poitype == 1).Count();
|
||||
}
|
||||
|
||||
private async Task UpdateTrip()
|
||||
{
|
||||
//Get Current Trip and Update it After TripPoints Creation
|
||||
CurrentTrip.Distance = 5.95;
|
||||
CurrentTrip.IsComplete = true;
|
||||
CurrentTrip.EndTimeStamp =
|
||||
CurrentTripPoints.Last<TripPoint>().RecordedTimeStamp.AddTicks(-1 * CurrentTripPoints.Last<TripPoint>().RecordedTimeStamp.Ticks % 10000);
|
||||
CurrentTrip.Rating = 90;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
await tripStore.UpdateItemAsync(CurrentTrip);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine($"Trip Statistics Update Failure : {DateTime.Now.ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateUserProfile()
|
||||
{
|
||||
|
||||
//Get User
|
||||
List<User> users = userStore.GetItemsAsync().Result;
|
||||
User CurrentUser = users.Where(u => u.UserId == "Hacker 1").SingleOrDefault();
|
||||
|
||||
//Update USer
|
||||
CurrentUser.TotalTrips++;
|
||||
CurrentUser.TotalDistance = CurrentUser.TotalDistance + CurrentTrip.Distance;
|
||||
CurrentUser.HardStops = CurrentUser.HardStops + CurrentTrip.HardStops;
|
||||
CurrentUser.HardAccelerations = CurrentUser.HardAccelerations + CurrentTrip.HardAccelerations;
|
||||
|
||||
try
|
||||
{
|
||||
string json = CurrentUser.ToJson();
|
||||
await userStore.UpdateItemAsync(CurrentUser);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine($"User Profile Update Failure : {DateTime.Now.ToString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
using DeviceSim.DataObjects.Models;
|
||||
using DeviceSim.Helpers;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace DeviceSim.Controllers
|
||||
{
|
||||
public class BaseTripController
|
||||
{
|
||||
protected internal mydrivingDBContext Ctx { get; set; }
|
||||
protected internal List<TripPointSource> TripPointSourceInfo { get; set; }
|
||||
protected internal List<Poisource> TripPOIsource { get; set; }
|
||||
|
||||
|
||||
|
||||
public BaseTripController(DBConnectionInfo dBConnectionInfo)
|
||||
{
|
||||
Ctx = new mydrivingDBContext(dBConnectionInfo);
|
||||
//Select Random Trip
|
||||
GetSampleTrip();
|
||||
//Default Constructor
|
||||
}
|
||||
|
||||
private void GetSampleTrip()
|
||||
{
|
||||
Random r = new Random();
|
||||
//Get Sample Trip Names
|
||||
List<string> tripNames = Ctx.TripPointSource.Select(p => p.Name).Distinct().ToList();
|
||||
//Choose Random Trip
|
||||
var tName = tripNames.ElementAt(r.Next(0, tripNames.Count));
|
||||
|
||||
//Get Source TripPoints for Random Trip
|
||||
TripPointSourceInfo = Ctx.TripPointSource.Where(p => p.Name == tName).ToList();
|
||||
//Get Source POIs for Random Trip
|
||||
TripPOIsource = Ctx.Poisource.Where(p => p.TripId == (TripPointSourceInfo.FirstOrDefault().Name)).ToList();
|
||||
//Console.WriteLine($"Sample Trip Selected: {tName}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
252
support/simulator/DeviceSim/Controllers/EFTripController.cs
Normal file
252
support/simulator/DeviceSim/Controllers/EFTripController.cs
Normal file
@ -0,0 +1,252 @@
|
||||
using DeviceSim.DataObjects.Models;
|
||||
using DeviceSim.Helpers;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace DeviceSim.Controllers
|
||||
{
|
||||
public class EFTripController : BaseTripController
|
||||
{
|
||||
#region Variables
|
||||
|
||||
|
||||
|
||||
private Trips CurrentTrip;
|
||||
|
||||
//private mydrivingDBContext ctx;
|
||||
//private List<TripPointSource> tripInfo;
|
||||
//private List<Poisource> tripPOIsource;
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
//Create Trips from Data in the Database
|
||||
public EFTripController(DBConnectionInfo dBConnectionInfo):base(dBConnectionInfo)
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public async Task CreateTrip()
|
||||
{
|
||||
//1 - Initialize Trip
|
||||
CurrentTrip = new Trips()
|
||||
{
|
||||
RecordedTimeStamp = DateTime.UtcNow,
|
||||
Name = $"Trip {DateTime.Now}",
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
UserId = "Hacker 1"
|
||||
};
|
||||
|
||||
CreateTripPoints();
|
||||
|
||||
//TODO : Do proper Distance Calculation and Add a method to determine Rating
|
||||
CurrentTrip.EndTimeStamp = CurrentTrip.TripPoints.Last<TripPoints>().RecordedTimeStamp;
|
||||
CurrentTrip.Rating = 90;
|
||||
//TODO : DO BingMaps Call to determine distance
|
||||
CurrentTrip.Distance = 5.95;
|
||||
|
||||
//Get Trip POIs and Update Trip Summary Information
|
||||
CreateTripPois();
|
||||
//Update Driver Profile with Trip Data
|
||||
UpdateUserProfile();
|
||||
|
||||
//Add trips to DB Instance
|
||||
await Ctx.Trips.AddAsync(CurrentTrip);
|
||||
|
||||
|
||||
}
|
||||
public async Task<bool> SaveChangesAsync()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await Ctx.SaveChangesAsync();
|
||||
Ctx.Dispose();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
//private void GetSampleTrip()
|
||||
//{
|
||||
// Random r = new Random();
|
||||
// //Get Sample Trip Names
|
||||
// List<string> tripNames = ctx.TripPointSource.Select(p => p.Name).Distinct().ToList();
|
||||
// //Choose Random Trip
|
||||
// var tName = tripNames.ElementAt(r.Next(0, tripNames.Count));
|
||||
|
||||
// //Get Source TripPoints for Random Trip
|
||||
// tripInfo = ctx.TripPointSource.Where(p => p.Name == tName).ToList();
|
||||
// //Get Source POIs for Random Trip
|
||||
// tripPOIsource = ctx.Poisource.Where(p => p.TripId == (tripInfo.FirstOrDefault().Name)).ToList();
|
||||
// //Console.WriteLine($"Sample Trip Selected: {tName}");
|
||||
|
||||
//}
|
||||
|
||||
private void CreateTripPois()
|
||||
{
|
||||
List<Pois> poiList = Ctx.Pois.Where(p => p.TripId == CurrentTrip.Id).ToList<Pois>();
|
||||
|
||||
//Generate POIs from Source
|
||||
foreach (var sPOI in TripPOIsource)
|
||||
{
|
||||
poiList.Add(new Pois
|
||||
{
|
||||
Id = Convert.ToString(Guid.NewGuid()), //New Guid
|
||||
TripId = CurrentTrip.Id, //Current Trips Id
|
||||
Latitude = sPOI.Latitude,
|
||||
Longitude = sPOI.Longitude,
|
||||
Poitype = sPOI.Poitype,
|
||||
RecordedTimeStamp = DateTime.Now.ToLongTimeString()
|
||||
});
|
||||
}
|
||||
|
||||
//Add POI's to Database Context
|
||||
Ctx.Pois.AddRangeAsync(poiList);
|
||||
|
||||
CurrentTrip.HardStops = poiList.Where(p => p.Poitype == 2).Count();
|
||||
CurrentTrip.HardAccelerations = poiList.Where(p => p.Poitype == 1).Count();
|
||||
}
|
||||
|
||||
private void UpdateUserProfile()
|
||||
{
|
||||
try
|
||||
{
|
||||
UserProfiles up = Ctx.UserProfiles
|
||||
.Where(user => user.UserId == CurrentTrip.UserId)
|
||||
.SingleOrDefault();
|
||||
|
||||
|
||||
up.TotalTrips++;
|
||||
up.TotalDistance += CurrentTrip.Distance;
|
||||
up.HardStops += CurrentTrip.HardStops;
|
||||
up.HardAccelerations += CurrentTrip.HardAccelerations;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Console.WriteLine($"Unable to Update User Profile. Ensure that the Trip UserProfile Matches with records in the database for Hacker 1, for more information see: {ex.Message}.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateTripPoints()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
foreach (var tps in TripPointSourceInfo)
|
||||
{
|
||||
TripPoints _tripPoint = new TripPoints()
|
||||
{
|
||||
TripId = CurrentTrip.Id,
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Latitude = Convert.ToDouble(tps.Lat),
|
||||
Longitude = Convert.ToDouble(tps.Lon),
|
||||
Speed = Convert.ToDouble(tps.Speed),
|
||||
RecordedTimeStamp = Convert.ToDateTime(tps.Recordedtimestamp),
|
||||
Sequence = Convert.ToInt32(tps.Sequence),
|
||||
Rpm = Convert.ToDouble(tps.Enginerpm),
|
||||
ShortTermFuelBank = Convert.ToDouble(tps.Shorttermfuelbank),
|
||||
LongTermFuelBank = Convert.ToDouble(tps.Longtermfuelbank),
|
||||
ThrottlePosition = Convert.ToDouble(tps.Throttleposition),
|
||||
RelativeThrottlePosition = Convert.ToDouble(tps.Relativethrottleposition),
|
||||
Runtime = Convert.ToDouble(tps.Runtime),
|
||||
DistanceWithMalfunctionLight = Convert.ToDouble(tps.Distancewithmil),
|
||||
EngineLoad = Convert.ToDouble(tps.Engineload),
|
||||
MassFlowRate = Convert.ToDouble(tps.Mafflowrate),
|
||||
EngineFuelRate = Convert.ToDouble(tps.Enginefuelrate)
|
||||
|
||||
};
|
||||
CurrentTrip.TripPoints.Add(_tripPoint);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Update Time Stamps to current date and times before sending to IOT Hub
|
||||
UpdateTripPointTimeStamps(CurrentTrip);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Could not create/update Trip Points. For more detail see: {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTripPointTimeStamps(Trips trip)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Sort Trip Points By Sequence Number
|
||||
CurrentTrip.TripPoints = CurrentTrip.TripPoints.OrderBy(p => p.Sequence).ToList();
|
||||
|
||||
List<timeInfo> timeToAdd = new List<timeInfo>();
|
||||
System.TimeSpan tDiff;
|
||||
|
||||
//Create a Variable to Track the Time Range as it Changes
|
||||
System.DateTime runningTime = CurrentTrip.RecordedTimeStamp;
|
||||
|
||||
//Calculate the Difference in time between Each Sequence Item
|
||||
for (int currentTripPoint = (CurrentTrip.TripPoints.Count - 1); currentTripPoint > -1; currentTripPoint--)
|
||||
{
|
||||
if (currentTripPoint > 0)
|
||||
{
|
||||
tDiff = CurrentTrip.TripPoints.ElementAt(currentTripPoint).RecordedTimeStamp
|
||||
- CurrentTrip.TripPoints.ElementAt(currentTripPoint - 1).RecordedTimeStamp;
|
||||
timeToAdd.Add(new timeInfo() { evtSeq = CurrentTrip.TripPoints.ElementAt(currentTripPoint).Sequence, tSpan = tDiff });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Sort List in order to Add time to Trip Points
|
||||
timeToAdd = timeToAdd.OrderBy(s => s.evtSeq).ToList();
|
||||
//Update Trip Points
|
||||
|
||||
for (int currentTripPoint = 1, timeToAddCollIdx = 0; currentTripPoint < CurrentTrip.TripPoints.Count; currentTripPoint++, timeToAddCollIdx++)
|
||||
{
|
||||
runningTime = runningTime.Add(timeToAdd[timeToAddCollIdx].tSpan);
|
||||
CurrentTrip.TripPoints.ElementAt(currentTripPoint).RecordedTimeStamp = runningTime;
|
||||
}
|
||||
|
||||
// Update Initial Trip Point
|
||||
CurrentTrip.TripPoints.ElementAt(0).RecordedTimeStamp = CurrentTrip.RecordedTimeStamp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Could not update Trip Time Stamps from Samples. for more info see:{ex.Message}.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
public struct timeInfo
|
||||
{
|
||||
public int evtSeq;
|
||||
public TimeSpan tSpan;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DeviceSim.EDataObjects.Models
|
||||
{
|
||||
public partial class Trips
|
||||
{
|
||||
//public IList<TripPoints> Points { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using DeviceSim.Helpers;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class mydrivingDBContext : DbContext
|
||||
{
|
||||
private string _connectionString;
|
||||
|
||||
public string connString
|
||||
{
|
||||
get { return _connectionString; }
|
||||
set { _connectionString = value; }
|
||||
}
|
||||
|
||||
public mydrivingDBContext(DBConnectionInfo dBConnectionInfo) : base()
|
||||
{
|
||||
ConnectionStringHelper csHelper = new ConnectionStringHelper(dBConnectionInfo);
|
||||
connString = csHelper.ConnectionString;
|
||||
}
|
||||
}
|
||||
}
|
18
support/simulator/DeviceSim/DataObjects/Models/Devices.cs
Normal file
18
support/simulator/DeviceSim/DataObjects/Models/Devices.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class Devices
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
public string UserProfileId { get; set; }
|
||||
|
||||
public UserProfiles UserProfile { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class IothubDatas
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
}
|
20
support/simulator/DeviceSim/DataObjects/Models/Pois.cs
Normal file
20
support/simulator/DeviceSim/DataObjects/Models/Pois.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class Pois
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string TripId { get; set; }
|
||||
public double Latitude { get; set; }
|
||||
public double Longitude { get; set; }
|
||||
public int Poitype { get; set; }
|
||||
public string RecordedTimeStamp { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
}
|
15
support/simulator/DeviceSim/DataObjects/Models/Poisource.cs
Normal file
15
support/simulator/DeviceSim/DataObjects/Models/Poisource.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class Poisource
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string TripId { get; set; }
|
||||
public double Latitude { get; set; }
|
||||
public double Longitude { get; set; }
|
||||
public int Poitype { get; set; }
|
||||
public string RecordedTimeStamp { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class TripPointSource
|
||||
{
|
||||
public string Tripid { get; set; }
|
||||
public string Userid { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Trippointid { get; set; }
|
||||
public decimal Lat { get; set; }
|
||||
public decimal Lon { get; set; }
|
||||
public int Speed { get; set; }
|
||||
public string Recordedtimestamp { get; set; }
|
||||
public int Sequence { get; set; }
|
||||
public int Enginerpm { get; set; }
|
||||
public int Shorttermfuelbank { get; set; }
|
||||
public int Longtermfuelbank { get; set; }
|
||||
public int Throttleposition { get; set; }
|
||||
public int Relativethrottleposition { get; set; }
|
||||
public int Runtime { get; set; }
|
||||
public int Distancewithmil { get; set; }
|
||||
public int Engineload { get; set; }
|
||||
public int Mafflowrate { get; set; }
|
||||
public string Outsidetemperature { get; set; }
|
||||
public int Enginefuelrate { get; set; }
|
||||
public int? Field21 { get; set; }
|
||||
}
|
||||
}
|
35
support/simulator/DeviceSim/DataObjects/Models/TripPoints.cs
Normal file
35
support/simulator/DeviceSim/DataObjects/Models/TripPoints.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class TripPoints
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string TripId { get; set; }
|
||||
public double Latitude { get; set; }
|
||||
public double Longitude { get; set; }
|
||||
public double Speed { get; set; }
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
public int Sequence { get; set; }
|
||||
public double Rpm { get; set; }
|
||||
public double ShortTermFuelBank { get; set; }
|
||||
public double LongTermFuelBank { get; set; }
|
||||
public double ThrottlePosition { get; set; }
|
||||
public double RelativeThrottlePosition { get; set; }
|
||||
public double Runtime { get; set; }
|
||||
public double DistanceWithMalfunctionLight { get; set; }
|
||||
public double EngineLoad { get; set; }
|
||||
public double MassFlowRate { get; set; }
|
||||
public double EngineFuelRate { get; set; }
|
||||
public string Vin { get; set; }
|
||||
public bool HasObddata { get; set; }
|
||||
public bool HasSimulatedObddata { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public Trips Trip { get; set; }
|
||||
}
|
||||
}
|
35
support/simulator/DeviceSim/DataObjects/Models/Trips.cs
Normal file
35
support/simulator/DeviceSim/DataObjects/Models/Trips.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class Trips
|
||||
{
|
||||
public Trips()
|
||||
{
|
||||
TripPoints = new HashSet<TripPoints>();
|
||||
//Points = new List<TripPoints>();
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
public DateTime EndTimeStamp { get; set; }
|
||||
public int Rating { get; set; }
|
||||
public bool IsComplete { get; set; }
|
||||
public bool HasSimulatedObddata { get; set; }
|
||||
public double AverageSpeed { get; set; }
|
||||
public double FuelUsed { get; set; }
|
||||
public long HardStops { get; set; }
|
||||
public long HardAccelerations { get; set; }
|
||||
public string MainPhotoUrl { get; set; }
|
||||
public double Distance { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public ICollection<TripPoints> TripPoints { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class UserProfiles
|
||||
{
|
||||
public UserProfiles()
|
||||
{
|
||||
Devices = new HashSet<Devices>();
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string ProfilePictureUri { get; set; }
|
||||
public int Rating { get; set; }
|
||||
public int Ranking { get; set; }
|
||||
public double TotalDistance { get; set; }
|
||||
public long TotalTrips { get; set; }
|
||||
public long TotalTime { get; set; }
|
||||
public long HardStops { get; set; }
|
||||
public long HardAccelerations { get; set; }
|
||||
public double FuelConsumption { get; set; }
|
||||
public double MaxSpeed { get; set; }
|
||||
public byte[] Version { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset? UpdatedAt { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public ICollection<Devices> Devices { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace DeviceSim.DataObjects.Models
|
||||
{
|
||||
public partial class mydrivingDBContext : DbContext
|
||||
{
|
||||
public virtual DbSet<Devices> Devices { get; set; }
|
||||
public virtual DbSet<IothubDatas> IothubDatas { get; set; }
|
||||
public virtual DbSet<Pois> Pois { get; set; }
|
||||
public virtual DbSet<TripPoints> TripPoints { get; set; }
|
||||
public virtual DbSet<Trips> Trips { get; set; }
|
||||
public virtual DbSet<UserProfiles> UserProfiles { get; set; }
|
||||
public virtual DbSet<Poisource> Poisource { get; set; }
|
||||
public virtual DbSet<TripPointSource> TripPointSource { get; set; }
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
optionsBuilder.UseSqlServer(connString);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Devices>(entity =>
|
||||
{
|
||||
entity.HasIndex(e => e.CreatedAt)
|
||||
.HasName("IX_CreatedAt")
|
||||
.ForSqlServerIsClustered();
|
||||
|
||||
entity.HasIndex(e => e.UserProfileId)
|
||||
.HasName("IX_UserProfile_Id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.UserProfileId)
|
||||
.HasColumnName("UserProfile_Id")
|
||||
.HasMaxLength(128);
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
|
||||
entity.HasOne(d => d.UserProfile)
|
||||
.WithMany(p => p.Devices)
|
||||
.HasForeignKey(d => d.UserProfileId)
|
||||
.HasConstraintName("FK_dbo.Devices_dbo.UserProfiles_UserProfile_Id");
|
||||
});
|
||||
|
||||
|
||||
modelBuilder.Entity<IothubDatas>(entity =>
|
||||
{
|
||||
entity.ToTable("IOTHubDatas");
|
||||
|
||||
entity.HasIndex(e => e.CreatedAt)
|
||||
.HasName("IX_CreatedAt")
|
||||
.ForSqlServerIsClustered();
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Pois>(entity =>
|
||||
{
|
||||
entity.ToTable("POIs");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.Poitype).HasColumnName("POIType");
|
||||
|
||||
entity.Property(e => e.RecordedTimeStamp).HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.Timestamp)
|
||||
.HasColumnType("datetime")
|
||||
.HasDefaultValueSql("('1900-01-01T00:00:00.000')");
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Poisource>(entity =>
|
||||
{
|
||||
entity.ToTable("POISource");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
entity.Property(e => e.Poitype).HasColumnName("POIType");
|
||||
|
||||
entity.Property(e => e.RecordedTimeStamp).HasMaxLength(50);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<TripPoints>(entity =>
|
||||
{
|
||||
entity.HasIndex(e => e.CreatedAt)
|
||||
.HasName("IX_CreatedAt")
|
||||
.ForSqlServerIsClustered();
|
||||
|
||||
entity.HasIndex(e => e.TripId)
|
||||
.HasName("IX_TripId");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.HasObddata).HasColumnName("HasOBDData");
|
||||
|
||||
entity.Property(e => e.HasSimulatedObddata).HasColumnName("HasSimulatedOBDData");
|
||||
|
||||
entity.Property(e => e.RecordedTimeStamp).HasColumnType("datetime");
|
||||
|
||||
entity.Property(e => e.Rpm).HasColumnName("RPM");
|
||||
|
||||
entity.Property(e => e.TripId).HasMaxLength(128);
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
|
||||
entity.Property(e => e.Vin).HasColumnName("VIN");
|
||||
|
||||
entity.HasOne(d => d.Trip)
|
||||
.WithMany(p => p.TripPoints)
|
||||
.HasForeignKey(d => d.TripId)
|
||||
.HasConstraintName("FK_dbo.TripPoints_dbo.Trips_TripId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<TripPointSource>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Trippointid);
|
||||
|
||||
entity.Property(e => e.Trippointid)
|
||||
.HasColumnName("trippointid")
|
||||
.HasMaxLength(36)
|
||||
.IsUnicode(false)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
entity.Property(e => e.Distancewithmil).HasColumnName("distancewithmil");
|
||||
|
||||
entity.Property(e => e.Enginefuelrate).HasColumnName("enginefuelrate");
|
||||
|
||||
entity.Property(e => e.Engineload).HasColumnName("engineload");
|
||||
|
||||
entity.Property(e => e.Enginerpm).HasColumnName("enginerpm");
|
||||
|
||||
entity.Property(e => e.Field21).HasColumnName("FIELD21");
|
||||
|
||||
entity.Property(e => e.Lat)
|
||||
.HasColumnName("lat")
|
||||
.HasColumnType("numeric(18, 15)");
|
||||
|
||||
entity.Property(e => e.Lon)
|
||||
.HasColumnName("lon")
|
||||
.HasColumnType("numeric(19, 14)");
|
||||
|
||||
entity.Property(e => e.Longtermfuelbank).HasColumnName("longtermfuelbank");
|
||||
|
||||
entity.Property(e => e.Mafflowrate).HasColumnName("mafflowrate");
|
||||
|
||||
entity.Property(e => e.Name)
|
||||
.HasColumnName("name")
|
||||
.HasMaxLength(30)
|
||||
.IsUnicode(false);
|
||||
|
||||
entity.Property(e => e.Outsidetemperature)
|
||||
.HasColumnName("outsidetemperature")
|
||||
.HasMaxLength(30)
|
||||
.IsUnicode(false);
|
||||
|
||||
entity.Property(e => e.Recordedtimestamp)
|
||||
.IsRequired()
|
||||
.HasColumnName("recordedtimestamp")
|
||||
.HasMaxLength(28)
|
||||
.IsUnicode(false);
|
||||
|
||||
entity.Property(e => e.Relativethrottleposition).HasColumnName("relativethrottleposition");
|
||||
|
||||
entity.Property(e => e.Runtime).HasColumnName("runtime");
|
||||
|
||||
entity.Property(e => e.Sequence).HasColumnName("sequence");
|
||||
|
||||
entity.Property(e => e.Shorttermfuelbank).HasColumnName("shorttermfuelbank");
|
||||
|
||||
entity.Property(e => e.Speed).HasColumnName("speed");
|
||||
|
||||
entity.Property(e => e.Throttleposition).HasColumnName("throttleposition");
|
||||
|
||||
entity.Property(e => e.Tripid)
|
||||
.IsRequired()
|
||||
.HasColumnName("tripid")
|
||||
.HasMaxLength(36)
|
||||
.IsUnicode(false);
|
||||
|
||||
entity.Property(e => e.Userid)
|
||||
.IsRequired()
|
||||
.HasColumnName("userid")
|
||||
.HasMaxLength(33)
|
||||
.IsUnicode(false);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Trips>(entity =>
|
||||
{
|
||||
entity.HasIndex(e => e.CreatedAt)
|
||||
.HasName("IX_CreatedAt")
|
||||
.ForSqlServerIsClustered();
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.EndTimeStamp).HasColumnType("datetime");
|
||||
|
||||
entity.Property(e => e.HasSimulatedObddata).HasColumnName("HasSimulatedOBDData");
|
||||
|
||||
entity.Property(e => e.RecordedTimeStamp).HasColumnType("datetime");
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<UserProfiles>(entity =>
|
||||
{
|
||||
entity.HasIndex(e => e.CreatedAt)
|
||||
.HasName("IX_CreatedAt")
|
||||
.ForSqlServerIsClustered();
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasMaxLength(128)
|
||||
.HasDefaultValueSql("(newid())");
|
||||
|
||||
entity.Property(e => e.CreatedAt).HasDefaultValueSql("(sysutcdatetime())");
|
||||
|
||||
entity.Property(e => e.Version)
|
||||
.IsRequired()
|
||||
.IsRowVersion();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
43
support/simulator/DeviceSim/DataObjects/MyDriving.Context.cs
Normal file
43
support/simulator/DeviceSim/DataObjects/MyDriving.Context.cs
Normal file
@ -0,0 +1,43 @@
|
||||
namespace DeviceSim.EF.SQL.DataObjects.Models
|
||||
{
|
||||
using System;
|
||||
//using System.Data.Entity;
|
||||
//using System.Data.Entity.Infrastructure;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
public partial class mydrivingDBEntities : DbContext
|
||||
{
|
||||
private string connectionString = "Server=tcp:mydrivingdbserver-or76fh5yqpqg2.database.windows.net,1433;Initial Catalog=mydrivingDB;Persist Security Info=False;User ID=YourUserName;Password=OpenHack-85439610;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
|
||||
//public mydrivingDBEntities()
|
||||
// : base("name=mydrivingDBEntities")
|
||||
//{
|
||||
//}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseSqlServer(connectionString);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
//throw new NotImplementedException("Change this Model");
|
||||
|
||||
}
|
||||
|
||||
//protected override void OnModelCreating(DbModelBuilder modelBuilder)
|
||||
//{
|
||||
// throw new UnintentionalCodeFirstException();
|
||||
//}
|
||||
|
||||
public virtual DbSet<Device> Devices { get; set; }
|
||||
public virtual DbSet<factMLOutputData> factMLOutputDatas { get; set; }
|
||||
public virtual DbSet<IOTHubData> IOTHubDatas { get; set; }
|
||||
public virtual DbSet<POIs> POIs { get; set; }
|
||||
public virtual DbSet<TripPoint> TripPoints { get; set; }
|
||||
public virtual DbSet<Trips> Trips { get; set; }
|
||||
public virtual DbSet<UserProfile> UserProfiles { get; set; }
|
||||
}
|
||||
}
|
44
support/simulator/DeviceSim/DeviceSim.csproj
Normal file
44
support/simulator/DeviceSim/DeviceSim.csproj
Normal file
@ -0,0 +1,44 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="DataObjects\Model\**" />
|
||||
<Compile Remove="Scripts\Database\**" />
|
||||
<EmbeddedResource Remove="DataObjects\Model\**" />
|
||||
<EmbeddedResource Remove="Scripts\Database\**" />
|
||||
<None Remove="DataObjects\Model\**" />
|
||||
<None Remove="Scripts\Database\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="DataObjects\MyDriving.Context.cs" />
|
||||
<Compile Remove="Controllers\FileService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Interfaces\" />
|
||||
<Folder Include="helm\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Devices" Version="1.6.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.7.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Simulator.DataStore.API\Simulator.DataStore.API.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DeviceSim.Helpers
|
||||
{
|
||||
public class ConnectionStringHelper
|
||||
{
|
||||
private string connectionString;
|
||||
public string ConnectionString
|
||||
{
|
||||
get => connectionString;
|
||||
private set => connectionString = value;
|
||||
}
|
||||
|
||||
private void ConnectionStringBuilder(DBConnectionInfo dBConnectionInfo)
|
||||
{
|
||||
ConnectionString = $"Server=tcp:{dBConnectionInfo.DBServer},1433;Initial Catalog={dBConnectionInfo.DBCatalog};Persist Security Info=False;User ID={dBConnectionInfo.DBUserName};Password={dBConnectionInfo.DBPassword};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=60";
|
||||
|
||||
}
|
||||
public ConnectionStringHelper(DBConnectionInfo dBConnectionInfo)
|
||||
{
|
||||
ConnectionStringBuilder(dBConnectionInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct DBConnectionInfo
|
||||
{
|
||||
public string DBServer;
|
||||
public string DBCatalog;
|
||||
public string DBUserName;
|
||||
public string DBPassword;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DeviceSim.Model
|
||||
{
|
||||
public class CustomContractResolver : DefaultContractResolver
|
||||
{
|
||||
public CustomContractResolver()
|
||||
{
|
||||
PropertyMappings = new Dictionary<string, string>
|
||||
{
|
||||
["Longitude"] = "Lon",
|
||||
["Latitude"] = "Lat",
|
||||
["ShortTermFuelBank"] = "ShortTermFuelBank1",
|
||||
["LongTermFuelBank"] = "LongTermFuelBank1",
|
||||
["MassFlowRate"] = "MAFFlowRate",
|
||||
["RPM"] = "EngineRPM",
|
||||
["Id"] = "TripPointId",
|
||||
["DistanceWithMalfunctionLight"] = "DistancewithMIL",
|
||||
["HasSimulatedOBDData"] = "IsSimulated",
|
||||
};
|
||||
|
||||
IgnoreProperties = new List<string> { "HasOBDData" };
|
||||
}
|
||||
|
||||
private Dictionary<string, string> PropertyMappings { get; }
|
||||
|
||||
private List<string> IgnoreProperties { get; }
|
||||
|
||||
protected override string ResolvePropertyName(string propertyName)
|
||||
{
|
||||
string resolvedName;
|
||||
var resolved = PropertyMappings.TryGetValue(propertyName, out resolvedName);
|
||||
return resolved ? resolvedName : base.ResolvePropertyName(propertyName);
|
||||
}
|
||||
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
JsonProperty property = base.CreateProperty(member, memberSerialization);
|
||||
|
||||
if (IgnoreProperties.Contains(property.PropertyName))
|
||||
{
|
||||
property.ShouldSerialize = p => false;
|
||||
}
|
||||
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
20
support/simulator/DeviceSim/Helpers/Logger.cs
Normal file
20
support/simulator/DeviceSim/Helpers/Logger.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DeviceSim.Interfaces;
|
||||
|
||||
namespace DeviceSim.Helpers
|
||||
{
|
||||
public class Logger : ILogger
|
||||
{
|
||||
public void Report(Exception exception, LogCategory category)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteMessage( LogLevel level, string message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
29
support/simulator/DeviceSim/Interfaces/ILogger.cs
Normal file
29
support/simulator/DeviceSim/Interfaces/ILogger.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DeviceSim.Interfaces
|
||||
{
|
||||
public interface ILogger
|
||||
{
|
||||
void WriteMessage(LogLevel level, string message);
|
||||
void Report(Exception exception, LogCategory category);
|
||||
}
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
CRITICAL = 0,
|
||||
ERROR = 1,
|
||||
WARNING = 2,
|
||||
INFO = 3,
|
||||
VERBOSE = 4
|
||||
}
|
||||
|
||||
public enum LogCategory
|
||||
{
|
||||
CONFIGERROR = 0,
|
||||
SQLERROR = 1 ,
|
||||
APIERROR =2
|
||||
}
|
||||
|
||||
}
|
106
support/simulator/DeviceSim/Program.cs
Normal file
106
support/simulator/DeviceSim/Program.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using DeviceSim.Controllers;
|
||||
using DeviceSim.Helpers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DeviceSim
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
#region Variables
|
||||
|
||||
private static DBConnectionInfo dBConnectionInfo;
|
||||
public static int WaitTime { get; private set; }
|
||||
public static string TeamName { get; private set; }
|
||||
public static bool UseApi { get; private set; }
|
||||
public static string UserApiEndPoint { get; private set; }
|
||||
public static string PoiApiEndPoint { get; private set; }
|
||||
public static string TripsApiEndPoint { get; private set; }
|
||||
|
||||
#endregion Variables
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
InitializeApp();
|
||||
UseApi = true;
|
||||
|
||||
Console.WriteLine($"***** {TeamName}-Driving Simulator *****");
|
||||
Console.WriteLine($"Currently Using API Routes : {UseApi.ToString()}");
|
||||
Console.WriteLine($"*Starting Simulator - A new trip will be created every {WaitTime / 1000} seconds *");
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
CreateTripAsync().Wait();
|
||||
Thread.Sleep(WaitTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task CreateTripAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Starting Trip Creation : {DateTime.Now}. ");
|
||||
await CreateTrip();
|
||||
Console.WriteLine($"Trip Completed at : {DateTime.Now}. ");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeApp()
|
||||
{
|
||||
IConfiguration funcConfiguration;
|
||||
var builder = new ConfigurationBuilder().AddEnvironmentVariables();
|
||||
funcConfiguration = builder.Build();
|
||||
|
||||
//Environmental Variables - Pass to Container
|
||||
|
||||
//Database Connection Information
|
||||
dBConnectionInfo.DBServer = funcConfiguration.GetSection("SQL_SERVER").Value;
|
||||
dBConnectionInfo.DBUserName = funcConfiguration.GetSection("SQL_USER").Value;
|
||||
dBConnectionInfo.DBPassword = funcConfiguration.GetSection("SQL_PASSWORD").Value;
|
||||
dBConnectionInfo.DBCatalog = "mydrivingDB";
|
||||
//Api Connection Information
|
||||
UseApi = Convert.ToBoolean(funcConfiguration.GetSection("USE_API").Value);
|
||||
UserApiEndPoint = funcConfiguration.GetSection("USER_ROOT_URL").Value;
|
||||
PoiApiEndPoint = funcConfiguration.GetSection("POI_ROOT_URL").Value;
|
||||
TripsApiEndPoint = funcConfiguration.GetSection("TRIPS_ROOT_URL").Value;
|
||||
//Execution Information
|
||||
WaitTime = Convert.ToInt32(funcConfiguration.GetSection("TRIP_FREQUENCY").Value ?? ("180000"));
|
||||
TeamName = funcConfiguration.GetSection("TEAM_NAME").Value ?? ("TEAM 01");
|
||||
}
|
||||
|
||||
private static async Task CreateTrip()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UseApi)
|
||||
{
|
||||
ApiTripController CurrentTrip = new ApiTripController(dBConnectionInfo, UserApiEndPoint, PoiApiEndPoint, TripsApiEndPoint);
|
||||
await CurrentTrip.CreateTrip();
|
||||
}
|
||||
else
|
||||
{
|
||||
EFTripController CurrentTrip = new EFTripController(dBConnectionInfo);
|
||||
await CurrentTrip.CreateTrip();
|
||||
await CurrentTrip.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;//do Nothing just continue throwing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5585
support/simulator/DeviceSim/TripFiles/trip1.csv
Normal file
5585
support/simulator/DeviceSim/TripFiles/trip1.csv
Normal file
File diff suppressed because it is too large
Load Diff
49
support/simulator/DeviceSimulator.sln
Normal file
49
support/simulator/DeviceSimulator.sln
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27428.2037
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simulator.DataStore.Abstractions", "Simulator.DataStore.Abstractions\Simulator.DataStore.Abstractions.csproj", "{0EC4A8BA-969B-4B29-8019-129B8EB4C987}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simulator.DataObjects", "Simulator.DataObjects\Simulator.DataObjects.csproj", "{FA75519F-4ECA-4702-AF22-FACE7AAC093B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceSim", "DeviceSim\DeviceSim.csproj", "{9D2E4ABE-A6CE-44ED-B038-BD11A1041DEE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simulator.DataStore.API", "Simulator.DataStore.API\Simulator.DataStore.API.csproj", "{41D10DD0-5B6B-4F15-B1A3-3EEC38F3093E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simulator.DataStore.EFSQL", "Simulator.DataStore.EFSQL\Simulator.DataStore.EFSQL.csproj", "{A603F820-DD74-4EAE-8251-ABCFB3BA9DD0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0EC4A8BA-969B-4B29-8019-129B8EB4C987}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0EC4A8BA-969B-4B29-8019-129B8EB4C987}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0EC4A8BA-969B-4B29-8019-129B8EB4C987}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0EC4A8BA-969B-4B29-8019-129B8EB4C987}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FA75519F-4ECA-4702-AF22-FACE7AAC093B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA75519F-4ECA-4702-AF22-FACE7AAC093B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA75519F-4ECA-4702-AF22-FACE7AAC093B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA75519F-4ECA-4702-AF22-FACE7AAC093B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9D2E4ABE-A6CE-44ED-B038-BD11A1041DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9D2E4ABE-A6CE-44ED-B038-BD11A1041DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9D2E4ABE-A6CE-44ED-B038-BD11A1041DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9D2E4ABE-A6CE-44ED-B038-BD11A1041DEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{41D10DD0-5B6B-4F15-B1A3-3EEC38F3093E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{41D10DD0-5B6B-4F15-B1A3-3EEC38F3093E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{41D10DD0-5B6B-4F15-B1A3-3EEC38F3093E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{41D10DD0-5B6B-4F15-B1A3-3EEC38F3093E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A603F820-DD74-4EAE-8251-ABCFB3BA9DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A603F820-DD74-4EAE-8251-ABCFB3BA9DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A603F820-DD74-4EAE-8251-ABCFB3BA9DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A603F820-DD74-4EAE-8251-ABCFB3BA9DD0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F2E1FBE3-FDCA-4F9B-9AA2-BB5489766503}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
27
support/simulator/Dockerfile
Normal file
27
support/simulator/Dockerfile
Normal file
@ -0,0 +1,27 @@
|
||||
#Pull Base Image
|
||||
FROM mcr.microsoft.com/dotnet/runtime:3.1-alpine AS base
|
||||
WORKDIR /app
|
||||
#Pull SDK Image to Build Solution
|
||||
FROM mcr.microsoft.com/dotnet/sdk:3.1-alpine AS build
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN dotnet restore -nowarn:msb3202,nu1503
|
||||
WORKDIR /src/DeviceSim
|
||||
RUN dotnet build -c Release -o /app
|
||||
#Build .net solution
|
||||
FROM build AS publish
|
||||
RUN dotnet publish -c Release -o /app
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
ENV SQL_USER="devopsohsa00" \
|
||||
SQL_PASSWORD="devopsohdevpwd-00" \
|
||||
SQL_SERVER="changeme.database.windows.net" \
|
||||
SQL_DBNAME="mydrivingDB" \
|
||||
TRIP_FREQUENCY="180000" \
|
||||
TEAM_NAME="devopsoh000test" \
|
||||
USER_ROOT_URL="https://openhack${RGSUFFIX}userprofile.azurewebsites.net"\
|
||||
POI_ROOT_URL="https://openhack${RGSUFFIX}poi.azurewebsites.net"\
|
||||
TRIPS_ROOT_URL="https://openhack${RGSUFFIX}trips.azurewebsites.net"
|
||||
COPY --from=publish /app .
|
||||
ENTRYPOINT ["dotnet", "DeviceSim.dll"]
|
20
support/simulator/Simulator.DataObjects/BaseDataObject.cs
Normal file
20
support/simulator/Simulator.DataObjects/BaseDataObject.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
|
||||
public interface IBaseDataObject
|
||||
{
|
||||
string Id { get; set; }
|
||||
}
|
||||
public class BaseDataObject: IBaseDataObject
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public BaseDataObject()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
public interface IBaseDataObject
|
||||
{
|
||||
string Id { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class BaseDataObject : IBaseDataObject
|
||||
{
|
||||
public BaseDataObject() { Id = Guid.NewGuid().ToString(); }
|
||||
|
||||
public string Id { get ; set ; }
|
||||
}
|
||||
}
|
39
support/simulator/Simulator.DataStore.API/DataObjects/Poi.cs
Normal file
39
support/simulator/Simulator.DataStore.API/DataObjects/Poi.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class Poi //: BaseDataObject
|
||||
{
|
||||
[JsonProperty("tripId")]
|
||||
public Guid TripId { get; set; }
|
||||
|
||||
[JsonProperty("latitude")]
|
||||
public double Latitude { get; set; }
|
||||
|
||||
[JsonProperty("longitude")]
|
||||
public double Longitude { get; set; }
|
||||
|
||||
[JsonProperty("poiType")]
|
||||
public long PoiType { get; set; }
|
||||
|
||||
[JsonProperty("timestamp")]
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
[JsonProperty("deleted")]
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
[JsonProperty("id")]
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public partial class Poi
|
||||
{
|
||||
public static Poi FromJson(string json) => JsonConvert.DeserializeObject<Poi>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class PoiSerializer
|
||||
{
|
||||
public static string ToJson(this Poi self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class Trip // : BaseDataObject
|
||||
{
|
||||
[JsonProperty("Id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("UserId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("RecordedTimeStamp")]
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("EndTimeStamp")]
|
||||
public DateTime EndTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("Rating")]
|
||||
public long Rating { get; set; }
|
||||
|
||||
[JsonProperty("IsComplete")]
|
||||
public bool IsComplete { get; set; }
|
||||
|
||||
[JsonProperty("HasSimulatedOBDData")]
|
||||
public bool HasSimulatedObdData { get; set; }
|
||||
|
||||
[JsonProperty("AverageSpeed")]
|
||||
public long AverageSpeed { get; set; }
|
||||
|
||||
[JsonProperty("FuelUsed")]
|
||||
public long FuelUsed { get; set; }
|
||||
|
||||
[JsonProperty("HardStops")]
|
||||
public long HardStops { get; set; }
|
||||
|
||||
[JsonProperty("HardAccelerations")]
|
||||
public long HardAccelerations { get; set; }
|
||||
|
||||
[JsonProperty("Distance")]
|
||||
public double Distance { get; set; }
|
||||
|
||||
[JsonProperty("Created")]
|
||||
public DateTime Created { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public partial class Trip
|
||||
{
|
||||
public static Trip FromJson(string json) => JsonConvert.DeserializeObject<Trip>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class TripSerializer
|
||||
{
|
||||
public static string ToJson(this Trip self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
|
||||
public partial class TripPoint//: BaseDataObject
|
||||
{
|
||||
[JsonProperty("Id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("TripId")]
|
||||
public Guid TripId { get; set; }
|
||||
|
||||
[JsonProperty("Latitude")]
|
||||
public double Latitude { get; set; }
|
||||
|
||||
[JsonProperty("Longitude")]
|
||||
public double Longitude { get; set; }
|
||||
|
||||
[JsonProperty("Speed")]
|
||||
public double Speed { get; set; }
|
||||
|
||||
[JsonProperty("RecordedTimeStamp")]
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("Sequence")]
|
||||
public int Sequence { get; set; }
|
||||
|
||||
[JsonProperty("RPM")]
|
||||
public double Rpm { get; set; }
|
||||
|
||||
[JsonProperty("ShortTermFuelBank")]
|
||||
public double ShortTermFuelBank { get; set; }
|
||||
|
||||
[JsonProperty("LongTermFuelBank")]
|
||||
public double LongTermFuelBank { get; set; }
|
||||
|
||||
[JsonProperty("ThrottlePosition")]
|
||||
public double ThrottlePosition { get; set; }
|
||||
|
||||
[JsonProperty("RelativeThrottlePosition")]
|
||||
public double RelativeThrottlePosition { get; set; }
|
||||
|
||||
[JsonProperty("Runtime")]
|
||||
public double Runtime { get; set; }
|
||||
|
||||
[JsonProperty("DistanceWithMalfunctionLight")]
|
||||
public double DistanceWithMalfunctionLight { get; set; }
|
||||
|
||||
[JsonProperty("EngineLoad")]
|
||||
public double EngineLoad { get; set; }
|
||||
|
||||
[JsonProperty("EngineFuelRate")]
|
||||
public double EngineFuelRate { get; set; }
|
||||
|
||||
[JsonProperty("VIN")]
|
||||
public Vin Vin { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public partial class Vin
|
||||
{
|
||||
[JsonProperty("String")]
|
||||
public string String { get; set; }
|
||||
|
||||
[JsonProperty("Valid")]
|
||||
public bool Valid { get; set; }
|
||||
}
|
||||
|
||||
public partial class TripPoint
|
||||
{
|
||||
public static TripPoint FromJson(string json) => JsonConvert.DeserializeObject<TripPoint>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class TripPointSerializer
|
||||
{
|
||||
public static string ToJson(this TripPoint self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
|
||||
internal static class Converter
|
||||
{
|
||||
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||
{
|
||||
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||
//DateParseHandling = DateParseHandling.None,
|
||||
//Converters = {new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.None } },
|
||||
};
|
||||
}
|
||||
}
|
104
support/simulator/Simulator.DataStore.API/DataObjects/User.cs
Normal file
104
support/simulator/Simulator.DataStore.API/DataObjects/User.cs
Normal file
@ -0,0 +1,104 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class User //: BaseDataObject
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[JsonProperty("firstName")]
|
||||
public string FirstName { get; set; }
|
||||
|
||||
[JsonProperty("lastName")]
|
||||
[JsonConverter(typeof(ParseStringConverter))]
|
||||
public long LastName { get; set; }
|
||||
|
||||
[JsonProperty("userId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("profilePictureUri")]
|
||||
public string ProfilePictureUri { get; set; }
|
||||
|
||||
[JsonProperty("rating")]
|
||||
public long Rating { get; set; }
|
||||
|
||||
[JsonProperty("ranking")]
|
||||
public long Ranking { get; set; }
|
||||
|
||||
[JsonProperty("totalDistance")]
|
||||
public double TotalDistance { get; set; }
|
||||
|
||||
[JsonProperty("totalTrips")]
|
||||
public long TotalTrips { get; set; }
|
||||
|
||||
[JsonProperty("totalTime")]
|
||||
public long TotalTime { get; set; }
|
||||
|
||||
[JsonProperty("hardStops")]
|
||||
public long HardStops { get; set; }
|
||||
|
||||
[JsonProperty("hardAccelerations")]
|
||||
public long HardAccelerations { get; set; }
|
||||
|
||||
[JsonProperty("fuelConsumption")]
|
||||
public long FuelConsumption { get; set; }
|
||||
|
||||
[JsonProperty("maxSpeed")]
|
||||
public long MaxSpeed { get; set; }
|
||||
|
||||
[JsonProperty("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[JsonProperty("createdAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("updatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[JsonProperty("deleted")]
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
|
||||
public partial class User
|
||||
{
|
||||
public static User FromJson(string json) => JsonConvert.DeserializeObject<User>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class UserSerializer
|
||||
{
|
||||
public static string ToJson(this User self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
|
||||
internal class ParseStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null) return null;
|
||||
var value = serializer.Deserialize<string>(reader);
|
||||
long l;
|
||||
if (Int64.TryParse(value, out l))
|
||||
{
|
||||
return l;
|
||||
}
|
||||
throw new Exception("Cannot unmarshal type long");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
|
||||
{
|
||||
if (untypedValue == null)
|
||||
{
|
||||
serializer.Serialize(writer, null);
|
||||
return;
|
||||
}
|
||||
var value = (long)untypedValue;
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
public static class HttpClientExtensions
|
||||
{
|
||||
public static Task<HttpResponseMessage> PatchAsJsonAsync<T>(this HttpClient client, string requestUri, T value)
|
||||
{
|
||||
//Ensure.Argument.NotNull(client, "client");
|
||||
//Ensure.Argument.NotNullOrEmpty(requestUri, "requestUri");
|
||||
//Ensure.Argument.NotNull(value, "value");
|
||||
|
||||
var content = new ObjectContent<T>(value, new JsonMediaTypeFormatter());
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
var request = new HttpRequestMessage(new HttpMethod("PATCH"), requestUri) { Content = content };
|
||||
|
||||
return client.SendAsync(request);
|
||||
}
|
||||
public async static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content)
|
||||
{
|
||||
var method = new HttpMethod("PATCH");
|
||||
|
||||
var request = new HttpRequestMessage(method, requestUri)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
|
||||
return await client.SendAsync(request);
|
||||
}
|
||||
|
||||
public async static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content)
|
||||
{
|
||||
var method = new HttpMethod("PATCH");
|
||||
|
||||
var request = new HttpRequestMessage(method, requestUri)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
|
||||
return await client.SendAsync(request);
|
||||
}
|
||||
|
||||
public async static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
|
||||
{
|
||||
var method = new HttpMethod("PATCH");
|
||||
|
||||
var request = new HttpRequestMessage(method, requestUri)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
|
||||
return await client.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
public async static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
|
||||
{
|
||||
var method = new HttpMethod("PATCH");
|
||||
|
||||
var request = new HttpRequestMessage(method, requestUri)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
|
||||
return await client.SendAsync(request, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simulator.DataStore.Abstractions
|
||||
{
|
||||
public interface IBaseStore<T>
|
||||
{
|
||||
Task InitializeStore(string EndPoint);
|
||||
Task<T> GetItemAsync(string id);
|
||||
Task<List<T>> GetItemsAsync();
|
||||
Task<T> CreateItemAsync(T item);
|
||||
Task<bool> UpdateItemAsync(T item);
|
||||
Task<bool> DeleteItemAsync(T item);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,28 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class BaseStore//<T> : IBaseStore<T> where T : class, IBaseDataObject, new()
|
||||
{
|
||||
public string EndPoint { get; set; }
|
||||
public HttpClient Client { get; set; }
|
||||
public DateTime DateTime { get; set; }
|
||||
|
||||
public Task InitializeStore(string EndPoint)
|
||||
{
|
||||
Client = new HttpClient();
|
||||
Client.BaseAddress = new Uri(EndPoint);
|
||||
Client.DefaultRequestHeaders.Accept.Clear();
|
||||
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
DateTime = DateTime.UtcNow;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
72
support/simulator/Simulator.DataStore.API/Stores/PoiStore.cs
Normal file
72
support/simulator/Simulator.DataStore.API/Stores/PoiStore.cs
Normal file
@ -0,0 +1,72 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class PoiStore : BaseStore, IBaseStore<Poi>
|
||||
{
|
||||
|
||||
public PoiStore(string EndPoint)
|
||||
{
|
||||
base.InitializeStore(EndPoint);
|
||||
}
|
||||
|
||||
public async Task<Poi> GetItemAsync(string id)
|
||||
{
|
||||
Poi poi = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"/api/poi/{id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
poi = await response.Content.ReadAsAsync<Poi>();
|
||||
}
|
||||
return poi;
|
||||
}
|
||||
|
||||
public async Task<List<Poi>> GetItemsAsync()
|
||||
{
|
||||
List<Poi> trips = null;
|
||||
HttpResponseMessage response = await Client.GetAsync("api/poi/");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
trips = await response.Content.ReadAsAsync<List<Poi>>();
|
||||
}
|
||||
return trips;
|
||||
}
|
||||
|
||||
public async Task<Poi> CreateItemAsync(Poi item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.PostAsJsonAsync<Poi>("api/poi", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
item = await response.Content.ReadAsAsync<Poi>();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateItemAsync(Poi item)
|
||||
{
|
||||
|
||||
HttpResponseMessage response = await Client.PatchAsJsonAsync($"api/poi/{item.Id}", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteItemAsync(Poi item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.DeleteAsync($"api/poi/{item.Id}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class TripPointStore : BaseStore, IBaseStore<TripPoint>
|
||||
{
|
||||
|
||||
public TripPointStore(string EndPoint)
|
||||
{
|
||||
base.InitializeStore(EndPoint);
|
||||
}
|
||||
public async Task<TripPoint> GetItemAsync(string id)
|
||||
{
|
||||
//Deviating implemetnation because of complxity of the nested API
|
||||
TripPoint tripPoint = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"/api/trips/{id}/trippoints/{id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
tripPoint = await response.Content.ReadAsAsync<TripPoint>();
|
||||
}
|
||||
return tripPoint;
|
||||
}
|
||||
|
||||
public async Task<TripPoint> GetItemAsync(TripPoint item)
|
||||
{
|
||||
//Deviating implemetnation because of complxity of the nested API
|
||||
TripPoint tripPoint = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"/api/trips/{item.TripId}/trippoints/{item.Id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
tripPoint = await response.Content.ReadAsAsync<TripPoint>();
|
||||
}
|
||||
return tripPoint;
|
||||
}
|
||||
|
||||
public Task<List<TripPoint>> GetItemsAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<List<TripPoint>> GetItemsAsync(Trip item)
|
||||
{
|
||||
List<TripPoint> tripPoints = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"api/trips/{item.Id}/trippoints");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
tripPoints = await response.Content.ReadAsAsync<List<TripPoint>>();
|
||||
}
|
||||
return tripPoints;
|
||||
}
|
||||
|
||||
public async Task<TripPoint> CreateItemAsync(TripPoint item)
|
||||
{
|
||||
string apiPath = $"api/trips/{item.TripId.ToString()}/trippoints";
|
||||
HttpResponseMessage response = await Client.PostAsJsonAsync<TripPoint>(apiPath, item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
|
||||
item = await response.Content.ReadAsAsync<TripPoint>();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public Task<bool> UpdateItemAsync(TripPoint item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> DeleteItemAsync(TripPoint item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class TripStore : BaseStore, IBaseStore<Trip>
|
||||
{
|
||||
public TripStore(string EndPoint)
|
||||
{
|
||||
base.InitializeStore(EndPoint);
|
||||
}
|
||||
|
||||
public async Task<Trip> GetItemAsync(string id)
|
||||
{
|
||||
Trip trip = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"/api/trips/{id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
trip = await response.Content.ReadAsAsync<Trip>();
|
||||
}
|
||||
return trip;
|
||||
}
|
||||
|
||||
public async Task<List<Trip>> GetItemsAsync()
|
||||
{
|
||||
List<Trip> trips = null;
|
||||
HttpResponseMessage response = await Client.GetAsync("api/trips/");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
trips = await response.Content.ReadAsAsync<List<Trip>>();
|
||||
}
|
||||
return trips;
|
||||
}
|
||||
|
||||
public async Task<Trip> CreateItemAsync(Trip item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.PostAsJsonAsync<Trip>("api/trips", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
item = await response.Content.ReadAsAsync<Trip>();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateItemAsync(Trip item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.PatchAsJsonAsync($"api/trips/{item.Id}", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteItemAsync(Trip item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.DeleteAsync($"api/trips/{item.Id}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class UserStore : BaseStore, IBaseStore<User>
|
||||
{
|
||||
public UserStore(string EndPoint)
|
||||
{
|
||||
base.InitializeStore(EndPoint);
|
||||
|
||||
}
|
||||
public async Task<User> GetItemAsync(string id)
|
||||
{
|
||||
User user = null;
|
||||
HttpResponseMessage response = await Client.GetAsync($"/api/user/{id}");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
user = await response.Content.ReadAsAsync<User>();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public async Task<List<User>> GetItemsAsync()
|
||||
{
|
||||
List<User> users = null;
|
||||
HttpResponseMessage response = await Client.GetAsync("api/user/");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
users = await response.Content.ReadAsAsync<List<User>>();
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
public async Task<User> CreateItemAsync(User item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.PostAsJsonAsync<User>("api/user-java", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
item = await response.Content.ReadAsAsync<User>();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateItemAsync(User item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.PatchAsJsonAsync($"api/user-java/{item.Id}", item);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteItemAsync(User item)
|
||||
{
|
||||
HttpResponseMessage response = await Client.DeleteAsync($"api/user-java/{item.UserId}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (response.IsSuccessStatusCode)
|
||||
response.Content.Headers.ContentType.MediaType = "application/json";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simulator.DataStore.Abstractions
|
||||
{
|
||||
public interface IBaseStore<T>
|
||||
{
|
||||
Task InitializeStoreAsync();
|
||||
|
||||
Task<T> GetItemAsync(string id);
|
||||
|
||||
Task<IEnumerable<T>> GetItemsAsync();
|
||||
|
||||
Task<bool> CreateItemAsync(T item);
|
||||
|
||||
Task<bool> UpdateItemAsync(T item);
|
||||
|
||||
Task<bool> DeleteItemAsync(T item);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="DataObjects\" />
|
||||
<Folder Include="Helpers\" />
|
||||
<Folder Include="Interfaces\" />
|
||||
<Folder Include="Stores\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,34 @@
|
||||
trigger:
|
||||
- none
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
||||
variables:
|
||||
- group: openhack
|
||||
- name: ServiceConnectionName
|
||||
value: AzureServiceConnection
|
||||
- name: RESOURCES_SUFFIX
|
||||
value: sqlsecrot
|
||||
- name: RESOURCE_GROUP_NAME
|
||||
value: $(RESOURCES_PREFIX)$(RESOURCES_SUFFIX)rg
|
||||
- name: workDir
|
||||
value: "$(System.DefaultWorkingDirectory)/support/sqlsecretrotation/iac/bicep"
|
||||
|
||||
steps:
|
||||
- task: AzureCLI@2
|
||||
displayName: "Deploy"
|
||||
inputs:
|
||||
azureSubscription: "$(ServiceConnectionName)"
|
||||
scriptType: "bash"
|
||||
scriptLocation: "inlineScript"
|
||||
inlineScript: |
|
||||
if [ $(az group exists --name $(RESOURCE_GROUP_NAME)) = false ]; then
|
||||
az group create --name $(RESOURCE_GROUP_NAME) --location $(LOCATION)
|
||||
fi
|
||||
az deployment group create \
|
||||
--name $(Build.BuildId) \
|
||||
--resource-group $(RESOURCE_GROUP_NAME) \
|
||||
--template-file main.bicep \
|
||||
--parameters keyVaultRgName='$(RESOURCES_PREFIX)rg' keyVaultName='$(RESOURCES_PREFIX)kv' resourcesPrefix='$(RESOURCES_PREFIX)' resourcesSuffix='$(RESOURCES_SUFFIX)'
|
||||
workingDirectory: $(workDir)
|
@ -0,0 +1,114 @@
|
||||
trigger:
|
||||
- none
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
||||
variables:
|
||||
- group: openhack
|
||||
- group: tfstate
|
||||
- name: ServiceConnectionName
|
||||
value: AzureServiceConnection
|
||||
- name: workDir
|
||||
value: "$(System.DefaultWorkingDirectory)/support/sqlsecretrotation"
|
||||
|
||||
stages:
|
||||
- stage: Provision
|
||||
displayName: Provision infrastructure
|
||||
jobs:
|
||||
- deployment: Provision
|
||||
displayName: Provision
|
||||
environment: sqlsecretrotation
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self
|
||||
- task: TerraformInstaller@0
|
||||
displayName: Setup Terraform
|
||||
inputs:
|
||||
terraformVersion: "latest"
|
||||
- task: TerraformCLI@0
|
||||
displayName: Terraform Init
|
||||
inputs:
|
||||
command: "init"
|
||||
workingDirectory: "$(workDir)/iac/terraform"
|
||||
backendType: "azurerm"
|
||||
backendServiceArm: "$(ServiceConnectionName)"
|
||||
backendAzureRmResourceGroupName: "$(TFSTATE_RESOURCES_GROUP_NAME)"
|
||||
backendAzureRmStorageAccountName: "$(TFSTATE_STORAGE_ACCOUNT_NAME)"
|
||||
backendAzureRmContainerName: "$(TFSTATE_STORAGE_CONTAINER_NAME)"
|
||||
backendAzureRmKey: "sqlsecrot.tfstate"
|
||||
allowTelemetryCollection: true
|
||||
- task: TerraformCLI@0
|
||||
displayName: Terraform Plan
|
||||
inputs:
|
||||
command: "plan"
|
||||
workingDirectory: "$(workDir)/iac/terraform"
|
||||
environmentServiceName: "$(ServiceConnectionName)"
|
||||
commandOptions: '-detailed-exitcode -var="location=$(LOCATION)" -var="resources_prefix=$(RESOURCES_PREFIX)" -var="secret_name=SQL-PASSWORD" -var="key_vault_name=$(RESOURCES_PREFIX)kv" -var="key_vault_resource_group_name=$(RESOURCES_PREFIX)rg"'
|
||||
publishPlanResults: "tfplan"
|
||||
allowTelemetryCollection: true
|
||||
- task: TerraformCLI@0
|
||||
displayName: Terraform Apply
|
||||
condition: eq(variables['TERRAFORM_PLAN_HAS_CHANGES'], 'true')
|
||||
inputs:
|
||||
command: "apply"
|
||||
workingDirectory: "$(workDir)/iac/terraform"
|
||||
environmentServiceName: "$(ServiceConnectionName)"
|
||||
commandOptions: '-var="location=$(LOCATION)" -var="resources_prefix=$(RESOURCES_PREFIX)" -var="secret_name=SQL-PASSWORD" -var="key_vault_name=$(RESOURCES_PREFIX)kv" -var="key_vault_resource_group_name=$(RESOURCES_PREFIX)rg"'
|
||||
allowTelemetryCollection: true
|
||||
|
||||
- stage: Build
|
||||
displayName: Build function
|
||||
dependsOn: Provision
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- job: Build
|
||||
displayName: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
- task: UseDotNet@2
|
||||
displayName: "Setup .NET Core"
|
||||
inputs:
|
||||
packageType: "sdk"
|
||||
version: "3.x"
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Build project
|
||||
inputs:
|
||||
command: "build"
|
||||
projects: "$(workDir)/src/*.csproj"
|
||||
arguments: "--output $(System.DefaultWorkingDirectory)/publish_output --configuration Release"
|
||||
workingDirectory: "$(workDir)/src"
|
||||
- task: ArchiveFiles@2
|
||||
displayName: "Archive files"
|
||||
inputs:
|
||||
rootFolderOrFile: "$(System.DefaultWorkingDirectory)/publish_output"
|
||||
includeRootFolder: false
|
||||
archiveType: "zip"
|
||||
archiveFile: "$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip"
|
||||
replaceExistingArchive: true
|
||||
- publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
|
||||
displayName: "Publish Artifact"
|
||||
artifact: drop
|
||||
|
||||
- stage: Deploy
|
||||
displayName: Deploy function
|
||||
dependsOn: Build
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- deployment: Deploy
|
||||
displayName: Deploy
|
||||
environment: sqlsecretrotation
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- task: AzureFunctionApp@1
|
||||
displayName: "Azure Functions deploy"
|
||||
inputs:
|
||||
azureSubscription: "AzureServiceConnection"
|
||||
appType: "functionApp"
|
||||
appName: "$(RESOURCES_PREFIX)secrotfunc"
|
||||
package: "$(Pipeline.Workspace)/drop/$(Build.BuildId).zip"
|
||||
deploymentMethod: "auto"
|
66
support/sqlsecretrotation/.github/workflows/workflow.bicep.sqlsecrot.yml
vendored
Normal file
66
support/sqlsecretrotation/.github/workflows/workflow.bicep.sqlsecrot.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
name: "Deploy - sqlsecrot (Bicep)"
|
||||
|
||||
# run manually
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
# Set envs
|
||||
env:
|
||||
WORKDIR: "support/sqlsecretrotation/iac/bicep"
|
||||
RESOURCES_SUFFIX: "sqlsecrot"
|
||||
# RESOURCES_PREFIX: "devopsoh44707" # hardcoded or dynamic based on repo name
|
||||
# LOCATION: "westus2" # hardcoded or get from secrets
|
||||
|
||||
# Set defaults for GitHub Actions runner
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "support/sqlsecretrotation/iac/bicep"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: "Deploy"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Checkout the repository to the GitHub Actions runner
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Get RESOURCES_PREFIX based on the repo name
|
||||
- name: Get repo name
|
||||
uses: actions/github-script@v5
|
||||
id: resources_prefix
|
||||
with:
|
||||
result-encoding: string
|
||||
script: return context.repo.repo.toLowerCase()
|
||||
|
||||
# Concat RG name
|
||||
- name: Get resource group name
|
||||
uses: actions/github-script@v5
|
||||
id: resource_group_name
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
const { RESOURCES_SUFFIX } = process.env
|
||||
const repo_name = "${{ steps.resources_prefix.outputs.result }}"
|
||||
return `${repo_name}${RESOURCES_SUFFIX}rg`
|
||||
|
||||
# Login to Azure with Service Principal
|
||||
- name: "Azure Login"
|
||||
uses: Azure/login@v1
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||
|
||||
# Deploy
|
||||
- name: "Deploy"
|
||||
uses: Azure/cli@1.0.4
|
||||
with:
|
||||
inlineScript: |
|
||||
if [ $(az group exists --name ${{ steps.resource_group_name.outputs.result }}) = false ]; then
|
||||
az group create --name ${{ steps.resource_group_name.outputs.result }} --location ${{ secrets.LOCATION }}
|
||||
fi
|
||||
az deployment group create \
|
||||
--name ${{ github.run_id }} \
|
||||
--resource-group ${{ steps.resource_group_name.outputs.result }} \
|
||||
--template-file ${{ env.WORKDIR }}/main.bicep \
|
||||
--parameters keyVaultRgName='${{ steps.resources_prefix.outputs.result }}rg' keyVaultName='${{ steps.resources_prefix.outputs.result }}kv' resourcesPrefix='${{ steps.resources_prefix.outputs.result }}' resourcesSuffix='${{ env.RESOURCES_SUFFIX }}'
|
35
support/sqlsecretrotation/iac/bicep/deploy.sh
Normal file
35
support/sqlsecretrotation/iac/bicep/deploy.sh
Normal file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare LOCATION=$1
|
||||
declare RESOURCES_PREFIX=$2
|
||||
declare RESOURCES_SUFFIX=$3
|
||||
declare KEY_VAULT_RESOURCE_GROUP_NAME=$4
|
||||
declare KEY_VAULT_NAME=$5
|
||||
|
||||
declare -r USAGE_HELP="Usage: ./deploy.sh <LOCATION> <RESOURCES_PREFIX> <RESOURCES_SUFFIX> <KEY_VAULT_RESOURCE_GROUP_NAME> <KEY_VAULT_NAME>"
|
||||
|
||||
if [ $# -ne 5 ]; then
|
||||
echo "${USAGE_HELP}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for programs
|
||||
if ! [ -x "$(command -v az)" ]; then
|
||||
echo "az is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "devvars.sh" ]; then
|
||||
. devvars.sh
|
||||
fi
|
||||
|
||||
RESOURCE_GROUP_NAME="${RESOURCES_PREFIX}${RESOURCES_SUFFIX}rg"
|
||||
|
||||
if [ $(az group exists --name "${RESOURCE_GROUP_NAME}") = false ]; then
|
||||
az group create --name "${RESOURCE_GROUP_NAME}" --location "${LOCATION}"
|
||||
fi
|
||||
|
||||
az deployment group create \
|
||||
--resource-group "${RESOURCE_GROUP_NAME}" \
|
||||
--template-file main.bicep \
|
||||
--parameters keyVaultRgName="${KEY_VAULT_RESOURCE_GROUP_NAME}" keyVaultName="${KEY_VAULT_NAME}" resourcesPrefix="${RESOURCES_PREFIX}" resourcesSuffix="${RESOURCES_SUFFIX}"
|
60
support/sqlsecretrotation/iac/bicep/keyVault.bicep
Normal file
60
support/sqlsecretrotation/iac/bicep/keyVault.bicep
Normal file
@ -0,0 +1,60 @@
|
||||
param keyVaultName string
|
||||
param functionAppId string
|
||||
param functionAppPrincipalId string
|
||||
param functionAppTenantId string
|
||||
param eventSubscriptionName string
|
||||
param secretName string
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults?tabs=bicep
|
||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
|
||||
name: keyVaultName
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults/accesspolicies?tabs=bicep
|
||||
resource keyVaultAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
|
||||
name: 'add'
|
||||
parent: keyVault
|
||||
properties: {
|
||||
accessPolicies: [
|
||||
{
|
||||
tenantId: functionAppTenantId
|
||||
objectId: functionAppPrincipalId
|
||||
permissions: {
|
||||
secrets: [
|
||||
'get'
|
||||
'list'
|
||||
'set'
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.eventgrid/eventsubscriptions?tabs=bicep
|
||||
resource keyVaultEventSubscription 'Microsoft.EventGrid/eventSubscriptions@2021-06-01-preview' = {
|
||||
name: eventSubscriptionName
|
||||
scope: keyVault
|
||||
properties: {
|
||||
destination: {
|
||||
endpointType: 'AzureFunction'
|
||||
properties: {
|
||||
maxEventsPerBatch: 1
|
||||
preferredBatchSizeInKilobytes: 64
|
||||
resourceId: '${functionAppId}/functions/AKVSQLRotation'
|
||||
}
|
||||
}
|
||||
filter: {
|
||||
subjectBeginsWith: secretName
|
||||
subjectEndsWith: secretName
|
||||
includedEventTypes: [
|
||||
'Microsoft.KeyVault.SecretNearExpiry'
|
||||
]
|
||||
}
|
||||
eventDeliverySchema: 'EventGridSchema'
|
||||
retryPolicy: {
|
||||
eventTimeToLiveInMinutes: 60
|
||||
maxDeliveryAttempts: 30
|
||||
}
|
||||
}
|
||||
}
|
115
support/sqlsecretrotation/iac/bicep/main.bicep
Normal file
115
support/sqlsecretrotation/iac/bicep/main.bicep
Normal file
@ -0,0 +1,115 @@
|
||||
param keyVaultRgName string = resourceGroup().name
|
||||
param keyVaultName string
|
||||
param resourcesPrefix string
|
||||
param resourcesSuffix string = 'sqlsecrot'
|
||||
param secretName string = 'SQL-PASSWORD'
|
||||
param repoUrl string = 'https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git'
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.storage/storageaccounts?tabs=bicep
|
||||
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
|
||||
name: '${resourcesPrefix}${resourcesSuffix}st'
|
||||
location: resourceGroup().location
|
||||
sku: {
|
||||
name: 'Standard_LRS'
|
||||
}
|
||||
kind: 'StorageV2'
|
||||
properties: {
|
||||
supportsHttpsTrafficOnly: true
|
||||
accessTier: 'Hot'
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/serverfarms?tabs=bicep
|
||||
resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
|
||||
name: '${resourcesPrefix}${resourcesSuffix}plan'
|
||||
location: resourceGroup().location
|
||||
sku: {
|
||||
name: 'Y1'
|
||||
tier: 'Dynamic'
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource functionApp 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}${resourcesSuffix}func'
|
||||
location: resourceGroup().location
|
||||
kind: 'functionapp'
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
enabled: true
|
||||
serverFarmId: appServicePlan.id
|
||||
httpsOnly: true
|
||||
siteConfig: {
|
||||
appSettings: [
|
||||
{
|
||||
name: 'AzureWebJobsStorage'
|
||||
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
|
||||
}
|
||||
{
|
||||
name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
|
||||
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
|
||||
}
|
||||
{
|
||||
name: 'WEBSITE_CONTENTSHARE'
|
||||
value: toLower('${resourcesPrefix}${resourcesSuffix}func')
|
||||
}
|
||||
{
|
||||
name: 'FUNCTIONS_EXTENSION_VERSION'
|
||||
value: '~3'
|
||||
}
|
||||
{
|
||||
name: 'FUNCTIONS_WORKER_RUNTIME'
|
||||
value: 'dotnet'
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: applicationInsights.properties.InstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: applicationInsights.properties.ConnectionString
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/sourcecontrols?tabs=bicep
|
||||
resource functionAppSourceControl 'Microsoft.Web/sites/sourcecontrols@2021-02-01' = {
|
||||
name: 'web'
|
||||
parent: functionApp
|
||||
properties: {
|
||||
repoUrl: repoUrl
|
||||
branch: 'main'
|
||||
isManualIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.insights/components?tabs=bicep
|
||||
resource applicationInsights 'microsoft.insights/components@2020-02-02' = {
|
||||
name: '${resourcesPrefix}${resourcesSuffix}appi'
|
||||
location: resourceGroup().location
|
||||
kind: 'web'
|
||||
properties: {
|
||||
Application_Type: 'web'
|
||||
}
|
||||
}
|
||||
|
||||
module keyVault './keyVault.bicep' = {
|
||||
name: 'keyVaultDeployment'
|
||||
params: {
|
||||
keyVaultName: keyVaultName
|
||||
functionAppId: functionApp.id
|
||||
functionAppTenantId: functionApp.identity.tenantId
|
||||
functionAppPrincipalId: functionApp.identity.principalId
|
||||
eventSubscriptionName: '${keyVaultName}-${secretName}-${functionApp.name}'
|
||||
secretName: secretName
|
||||
}
|
||||
scope: resourceGroup(keyVaultRgName)
|
||||
dependsOn: [
|
||||
functionApp
|
||||
functionAppSourceControl
|
||||
]
|
||||
}
|
94
support/sqlsecretrotation/iac/terraform/deploy.sh
Normal file
94
support/sqlsecretrotation/iac/terraform/deploy.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare LOCATION=$1
|
||||
declare RESOURCES_PREFIX=$2
|
||||
declare SECRET_NAME=$3
|
||||
declare KEY_VAULT_RESOURCE_GROUP_NAME=$4
|
||||
declare KEY_VAULT_NAME=$5
|
||||
|
||||
declare -r USAGE_HELP="Usage: ./deploy.sh <LOCATION> <RESOURCES_PREFIX> <SECRET_NAME> <KEY_VAULT_RESOURCE_GROUP_NAME> <KEY_VAULT_NAME>"
|
||||
|
||||
if [ $# -ne 5 ]; then
|
||||
echo "${USAGE_HELP}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for programs
|
||||
if ! [ -x "$(command -v az)" ]; then
|
||||
echo "az is not installed!"
|
||||
exit 1
|
||||
elif ! [ -x "$(command -v terraform)" ]; then
|
||||
echo "terraform is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "devvars.sh" ]; then
|
||||
. devvars.sh
|
||||
fi
|
||||
|
||||
export ARM_THREEPOINTZERO_BETA_RESOURCES=true
|
||||
|
||||
azure_login() {
|
||||
_azuresp_json=$(cat azuresp.json)
|
||||
export ARM_CLIENT_ID=$(echo "${_azuresp_json}" | jq -r ".clientId")
|
||||
export ARM_CLIENT_SECRET=$(echo "${_azuresp_json}" | jq -r ".clientSecret")
|
||||
export ARM_SUBSCRIPTION_ID=$(echo "${_azuresp_json}" | jq -r ".subscriptionId")
|
||||
export ARM_TENANT_ID=$(echo "${_azuresp_json}" | jq -r ".tenantId")
|
||||
az login --service-principal --username "${ARM_CLIENT_ID}" --password "${ARM_CLIENT_SECRET}" --tenant "${ARM_TENANT_ID}"
|
||||
az account set --subscription "${ARM_SUBSCRIPTION_ID}"
|
||||
}
|
||||
|
||||
prepare_tfvars() {
|
||||
echo "Generating tfvars..."
|
||||
echo 'location = "'${LOCATION}'"' > terraform.tfvars
|
||||
echo 'resources_prefix = "'${RESOURCES_PREFIX}'"' >> terraform.tfvars
|
||||
echo 'secret_name = "'${SECRET_NAME}'"' >> terraform.tfvars
|
||||
echo 'key_vault_resource_group_name = "'${KEY_VAULT_RESOURCE_GROUP_NAME}'"' >> terraform.tfvars
|
||||
echo 'key_vault_name = "'${KEY_VAULT_NAME}'"' >> terraform.tfvars
|
||||
terraform fmt
|
||||
}
|
||||
|
||||
lint_terraform(){
|
||||
terraform fmt -check
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Terraform files are not properly formatted!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
init_terrafrom() {
|
||||
terraform init -backend-config=storage_account_name="${TFSTATE_STORAGE_ACCOUNT_NAME}" -backend-config=container_name="${TFSTATE_STORAGE_CONTAINER_NAME}" -backend-config=key="${TFSTATE_KEY_SECROT}" -backend-config=resource_group_name="${TFSTATE_RESOURCES_GROUP_NAME}"
|
||||
}
|
||||
|
||||
init_terrafrom_local() {
|
||||
terraform init -backend=false
|
||||
}
|
||||
|
||||
validate_terraform(){
|
||||
terraform validate
|
||||
}
|
||||
|
||||
preview_terraform(){
|
||||
terraform plan --detailed-exitcode
|
||||
return $?
|
||||
}
|
||||
|
||||
deploy_terraform(){
|
||||
local _tfplan_exit_code=${1}
|
||||
|
||||
terraform apply --auto-approve
|
||||
}
|
||||
|
||||
destroy_terraform(){
|
||||
terraform destroy --auto-approve
|
||||
}
|
||||
|
||||
prepare_tfvars
|
||||
azure_login
|
||||
lint_terraform
|
||||
init_terrafrom
|
||||
# init_terrafrom_local
|
||||
validate_terraform
|
||||
preview_terraform
|
||||
deploy_terraform $?
|
||||
# destroy_terraform
|
8
support/sqlsecretrotation/iac/terraform/locals.tf
Normal file
8
support/sqlsecretrotation/iac/terraform/locals.tf
Normal file
@ -0,0 +1,8 @@
|
||||
locals {
|
||||
suffix = "sqlsecrot"
|
||||
resource_group_name = "${var.resources_prefix}${local.suffix}rg"
|
||||
storage_account_name = "${var.resources_prefix}${local.suffix}st"
|
||||
function_app_name = "${var.resources_prefix}${local.suffix}func"
|
||||
app_service_plan_name = "${var.resources_prefix}${local.suffix}plan"
|
||||
application_insights_name = "${var.resources_prefix}${local.suffix}appi"
|
||||
}
|
132
support/sqlsecretrotation/iac/terraform/main.tf
Normal file
132
support/sqlsecretrotation/iac/terraform/main.tf
Normal file
@ -0,0 +1,132 @@
|
||||
data "azurerm_key_vault" "key_vault" {
|
||||
name = var.key_vault_name
|
||||
resource_group_name = var.key_vault_resource_group_name
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "resource_group" {
|
||||
name = local.resource_group_name
|
||||
location = var.location
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_storage_account" "storage_account" {
|
||||
name = local.storage_account_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
account_tier = "Standard"
|
||||
account_replication_type = "LRS"
|
||||
min_tls_version = "TLS1_2"
|
||||
enable_https_traffic_only = true
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_application_insights" "application_insights" {
|
||||
name = local.application_insights_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
application_type = "web"
|
||||
}
|
||||
|
||||
resource "azurerm_app_service_plan" "app_service_plan" {
|
||||
name = local.app_service_plan_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
kind = "FunctionApp"
|
||||
|
||||
sku {
|
||||
tier = "Dynamic"
|
||||
size = "Y1"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
kind
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_function_app" "function_app" {
|
||||
name = local.function_app_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
storage_account_name = azurerm_storage_account.storage_account.name
|
||||
storage_account_access_key = azurerm_storage_account.storage_account.primary_access_key
|
||||
version = "~3"
|
||||
https_only = true
|
||||
|
||||
app_settings = {
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"FUNCTIONS_WORKER_RUNTIME" = "dotnet"
|
||||
}
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
site_config {
|
||||
ftps_state = "Disabled"
|
||||
dotnet_framework_version = "v4.0"
|
||||
use_32_bit_worker_process = false
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
# app_settings["WEBSITE_ENABLE_SYNC_UPDATE_SITE"],
|
||||
# app_settings["WEBSITE_RUN_FROM_PACKAGE"],
|
||||
# app_settings["APPINSIGHTS_INSTRUMENTATIONKEY"],
|
||||
# app_settings["FUNCTIONS_WORKER_RUNTIME"]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_source_control
|
||||
# resource "azurerm_app_service_source_control" "app_service_source_control" {
|
||||
# app_id = azurerm_function_app.function_app.id
|
||||
# repo_url = "https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git"
|
||||
# branch = "main"
|
||||
# manual_integration = true
|
||||
# # scm_type = "ExternalGit"
|
||||
# }
|
||||
|
||||
resource "azurerm_key_vault_access_policy" "key_vault_access_policy_function_app" {
|
||||
key_vault_id = data.azurerm_key_vault.key_vault.id
|
||||
tenant_id = azurerm_function_app.function_app.identity[0].tenant_id
|
||||
object_id = azurerm_function_app.function_app.identity[0].principal_id
|
||||
|
||||
secret_permissions = [
|
||||
"Get", "List", "Set"
|
||||
]
|
||||
}
|
||||
|
||||
# resource "azurerm_eventgrid_event_subscription" "eventgrid_event_subscription" {
|
||||
# name = "${data.azurerm_key_vault.key_vault.name}-${var.secret_name}-${azurerm_function_app.function_app.name}"
|
||||
# scope = data.azurerm_key_vault.key_vault.id
|
||||
|
||||
# azure_function_endpoint {
|
||||
# function_id = "${azurerm_function_app.function_app.id}/functions/AKVSQLRotation"
|
||||
# max_events_per_batch = 1
|
||||
# preferred_batch_size_in_kilobytes = 64
|
||||
# }
|
||||
|
||||
# subject_filter {
|
||||
# subject_begins_with = var.secret_name
|
||||
# subject_ends_with = var.secret_name
|
||||
# }
|
||||
|
||||
# included_event_types = [
|
||||
# "Microsoft.KeyVault.SecretNearExpiry"
|
||||
# ]
|
||||
# }
|
16
support/sqlsecretrotation/iac/terraform/providers.tf
Normal file
16
support/sqlsecretrotation/iac/terraform/providers.tf
Normal file
@ -0,0 +1,16 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.94.0"
|
||||
}
|
||||
}
|
||||
backend "azurerm" {
|
||||
}
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "current" {}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
24
support/sqlsecretrotation/iac/terraform/variables.tf
Normal file
24
support/sqlsecretrotation/iac/terraform/variables.tf
Normal file
@ -0,0 +1,24 @@
|
||||
variable "key_vault_resource_group_name" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "key_vault_name" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "resources_prefix" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "secret_name" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
1
support/sqlsecretrotation/src/.dockerignore
Normal file
1
support/sqlsecretrotation/src/.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
local.settings.json
|
28
support/sqlsecretrotation/src/AKVSQLRotation.cs
Normal file
28
support/sqlsecretrotation/src/AKVSQLRotation.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Default URL for triggering event grid function in the local environment.
|
||||
// http://localhost:7071/runtime/webhooks/EventGrid?functionName={functionname}
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
|
||||
using Azure.Messaging.EventGrid;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.KeyVault
|
||||
{
|
||||
public static class AKVSQLRotation
|
||||
{
|
||||
|
||||
[FunctionName("AKVSQLRotation")]
|
||||
public static void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
|
||||
{
|
||||
log.LogInformation("C# Event trigger function processed a request.");
|
||||
var secretName = eventGridEvent.Subject;
|
||||
var secretVersion = Regex.Match(eventGridEvent.Data.ToString(), "Version\":\"([a-z0-9]*)").Groups[1].ToString();
|
||||
var keyVaultName = Regex.Match(eventGridEvent.Topic, ".vaults.(.*)").Groups[1].ToString();
|
||||
log.LogInformation($"Key Vault Name: {keyVaultName}");
|
||||
log.LogInformation($"Secret Name: {secretName}");
|
||||
log.LogInformation($"Secret Version: {secretVersion}");
|
||||
|
||||
SecretRotator.RotateSecret(log, secretName, keyVaultName);
|
||||
}
|
||||
}
|
||||
}
|
31
support/sqlsecretrotation/src/AKVSQLRotationHttp.cs
Normal file
31
support/sqlsecretrotation/src/AKVSQLRotationHttp.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.KeyVault
|
||||
{
|
||||
public static class AKVSQLRotationHttp
|
||||
{
|
||||
[FunctionName("AKVSQLRotationHttp")]
|
||||
public static IActionResult Run(
|
||||
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
|
||||
ILogger log)
|
||||
{
|
||||
string keyVaultName = req.Query["KeyVaultName"];
|
||||
string secretName = req.Query["SecretName"];
|
||||
if (string.IsNullOrEmpty(keyVaultName) || string.IsNullOrEmpty(secretName))
|
||||
{
|
||||
return new BadRequestObjectResult("Please pass a KeyVaultName and SecretName on the query string");
|
||||
}
|
||||
|
||||
log.LogInformation(req.ToString());
|
||||
|
||||
log.LogInformation("C# Http trigger function processed a request.");
|
||||
SecretRotator.RotateSecret(log, secretName, keyVaultName);
|
||||
|
||||
return new OkObjectResult($"Secret Rotated Successfully");
|
||||
}
|
||||
}
|
||||
}
|
14
support/sqlsecretrotation/src/Dockerfile
Normal file
14
support/sqlsecretrotation/src/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS installer-env
|
||||
|
||||
COPY . /src/dotnet-function-app
|
||||
RUN cd /src/dotnet-function-app && \
|
||||
mkdir -p /home/site/wwwroot && \
|
||||
dotnet publish *.csproj --output /home/site/wwwroot
|
||||
|
||||
# To enable ssh & remote debugging on app service change the base image to the one below
|
||||
# FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice
|
||||
FROM mcr.microsoft.com/azure-functions/dotnet:3.0-slim
|
||||
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
|
||||
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
|
||||
|
||||
COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]
|
@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
|
||||
<RootNamespace>Microsoft.KeyVault</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Messaging.EventGrid" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventGrid" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.13" />
|
||||
<PackageReference Include="Azure.Identity" Version="1.5.0" />
|
||||
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="3.0.1" />
|
||||
<PackageReference Include="Azure.Core" Version="1.20.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="host.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="local.settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
116
support/sqlsecretrotation/src/SecretRotator.cs
Normal file
116
support/sqlsecretrotation/src/SecretRotator.cs
Normal file
@ -0,0 +1,116 @@
|
||||
using Azure.Security.KeyVault.Secrets;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Azure.Identity;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Microsoft.KeyVault
|
||||
{
|
||||
public class SecretRotator
|
||||
{
|
||||
private const string CredentialIdTag = "CredentialId";
|
||||
private const string ProviderAddressTag = "ProviderAddress";
|
||||
private const string ValidityPeriodDaysTag = "ValidityPeriodDays";
|
||||
|
||||
public static void RotateSecret(ILogger log, string secretName, string keyVaultName)
|
||||
{
|
||||
//Retrieve Current Secret
|
||||
var kvUri = "https://" + keyVaultName + ".vault.azure.net";
|
||||
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
|
||||
KeyVaultSecret secret = client.GetSecret(secretName);
|
||||
log.LogInformation("Secret Info Retrieved");
|
||||
|
||||
//Retrieve Secret Info
|
||||
var credentialId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
|
||||
var providerAddress = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
|
||||
var validityPeriodDays = secret.Properties.Tags.ContainsKey(ValidityPeriodDaysTag) ? secret.Properties.Tags[ValidityPeriodDaysTag] : "";
|
||||
log.LogInformation($"Provider Address: {providerAddress}");
|
||||
log.LogInformation($"Credential Id: {credentialId}");
|
||||
|
||||
//Check Service Provider connection
|
||||
CheckServiceConnection(secret);
|
||||
log.LogInformation("Service Connection Validated");
|
||||
|
||||
//Create new password
|
||||
var randomPassword = CreateRandomPassword();
|
||||
log.LogInformation("New Password Generated");
|
||||
|
||||
//Add secret version with new password to Key Vault
|
||||
CreateNewSecretVersion(client, secret, randomPassword);
|
||||
log.LogInformation("New Secret Version Generated");
|
||||
|
||||
//Update Service Provider with new password
|
||||
UpdateServicePassword(secret, randomPassword);
|
||||
log.LogInformation("Password Changed");
|
||||
log.LogInformation($"Secret Rotated Successfully");
|
||||
}
|
||||
|
||||
private static void CreateNewSecretVersion(SecretClient client, KeyVaultSecret secret, string newSecretValue)
|
||||
{
|
||||
var credentialId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
|
||||
var providerAddress = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
|
||||
var validityPeriodDays = secret.Properties.Tags.ContainsKey(ValidityPeriodDaysTag) ? secret.Properties.Tags[ValidityPeriodDaysTag] : "60";
|
||||
|
||||
//add new secret version to key vault
|
||||
var newSecret = new KeyVaultSecret(secret.Name, newSecretValue);
|
||||
newSecret.Properties.Tags.Add(CredentialIdTag, credentialId);
|
||||
newSecret.Properties.Tags.Add(ProviderAddressTag, providerAddress);
|
||||
newSecret.Properties.Tags.Add(ValidityPeriodDaysTag, validityPeriodDays);
|
||||
newSecret.Properties.ExpiresOn = DateTime.UtcNow.AddDays(Int32.Parse(validityPeriodDays));
|
||||
client.SetSecret(newSecret);
|
||||
}
|
||||
|
||||
private static void UpdateServicePassword(KeyVaultSecret secret, string newpassword)
|
||||
{
|
||||
var userId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
|
||||
var datasource = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
|
||||
var dbResourceId = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
|
||||
|
||||
var dbName = dbResourceId.Split('/')[8];
|
||||
var password = secret.Value;
|
||||
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||
builder.DataSource = $"{dbName}.database.windows.net";
|
||||
builder.UserID = userId;
|
||||
builder.Password = password;
|
||||
|
||||
//Update password
|
||||
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
using (SqlCommand command = new SqlCommand($"ALTER LOGIN {userId} WITH Password='{newpassword}';", connection))
|
||||
{
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string CreateRandomPassword()
|
||||
{
|
||||
const int length = 60;
|
||||
|
||||
byte[] randomBytes = new byte[length];
|
||||
RNGCryptoServiceProvider rngCrypt = new RNGCryptoServiceProvider();
|
||||
rngCrypt.GetBytes(randomBytes);
|
||||
return Convert.ToBase64String(randomBytes);
|
||||
}
|
||||
private static void CheckServiceConnection(KeyVaultSecret secret)
|
||||
{
|
||||
var userId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
|
||||
var dbResourceId = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
|
||||
|
||||
var dbName = dbResourceId.Split('/')[8];
|
||||
var password = secret.Value;
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||
builder.DataSource = $"{dbName}.database.windows.net";
|
||||
builder.UserID = userId;
|
||||
builder.Password = password;
|
||||
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
support/sqlsecretrotation/src/host.json
Normal file
11
support/sqlsecretrotation/src/host.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"logging": {
|
||||
"applicationInsights": {
|
||||
"samplingExcludedTypes": "Request",
|
||||
"samplingSettings": {
|
||||
"isEnabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
support/sqlsecretrotation/src/local.settings.json
Normal file
7
support/sqlsecretrotation/src/local.settings.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"IsEncrypted": false,
|
||||
"Values": {
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
|
||||
}
|
||||
}
|
25
support/tripviewer/.dockerignore
Normal file
25
support/tripviewer/.dockerignore
Normal file
@ -0,0 +1,25 @@
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
19
support/tripviewer/Dockerfile
Normal file
19
support/tripviewer/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN dotnet publish "web/TripViewer.csproj" -c Release -o /publish
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine
|
||||
ENV USER_ROOT_URL="https://devopsohuserprofile.azurewebsites.net"
|
||||
ENV POI_ROOT_URL="https://devopsohpoi.azurewebsites.net"
|
||||
ENV TRIPS_ROOT_URL="https://devopsohtrips.azurewebsites.net"
|
||||
ENV USER_JAVA_ROOT_URL="https://devopsohuserjava.azurewebsites.net"
|
||||
ENV STAGING_USER_ROOT_URL="https://devopsohuserprofile-staging.azurewebsites.net"
|
||||
ENV STAGING_POI_ROOT_URL="https://devopsohpoi-staging.azurewebsites.net"
|
||||
ENV STAGING_TRIPS_ROOT_URL="https://devopsohtrips-staging.azurewebsites.net"
|
||||
ENV STAGING_USER_JAVA_ROOT_URL="https://devopsohuserjava-staging.azurewebsites.net"
|
||||
ENV BING_MAPS_KEY="changeme"
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=build /publish .
|
||||
ENTRYPOINT ["dotnet", "TripViewer.dll"]
|
25
support/tripviewer/TripViewer.sln
Normal file
25
support/tripviewer/TripViewer.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripViewer", "web/TripViewer.csproj", "{49FBE870-AFE2-406E-8B4B-026182DF3BB9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{49FBE870-AFE2-406E-8B4B-026182DF3BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{49FBE870-AFE2-406E-8B4B-026182DF3BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{49FBE870-AFE2-406E-8B4B-026182DF3BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{49FBE870-AFE2-406E-8B4B-026182DF3BB9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FB2EF42E-DCDC-498A-9B16-83AE0B217D2A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
48
support/tripviewer/web/Controllers/HomeController.cs
Normal file
48
support/tripviewer/web/Controllers/HomeController.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using TripViewer.Models;
|
||||
using TripViewer.Utility;
|
||||
|
||||
namespace TripViewer.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
private readonly IConfiguration Configuration;
|
||||
|
||||
public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
TripViewerConfiguration tv = new TripViewerConfiguration
|
||||
{
|
||||
USER_ROOT_URL = Configuration.GetValue<string>("USER_ROOT_URL"),
|
||||
USER_JAVA_ROOT_URL = Configuration.GetValue<string>("USER_JAVA_ROOT_URL"),
|
||||
TRIPS_ROOT_URL = Configuration.GetValue<string>("TRIPS_ROOT_URL"),
|
||||
POI_ROOT_URL = Configuration.GetValue<string>("POI_ROOT_URL"),
|
||||
STAGING_USER_ROOT_URL = Configuration.GetValue<string>("STAGING_USER_ROOT_URL"),
|
||||
STAGING_USER_JAVA_ROOT_URL = Configuration.GetValue<string>("STAGING_USER_JAVA_ROOT_URL"),
|
||||
STAGING_TRIPS_ROOT_URL = Configuration.GetValue<string>("STAGING_TRIPS_ROOT_URL"),
|
||||
STAGING_POI_ROOT_URL = Configuration.GetValue<string>("STAGING_POI_ROOT_URL")
|
||||
};
|
||||
return View(tv);
|
||||
}
|
||||
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
}
|
||||
}
|
67
support/tripviewer/web/Controllers/TripController.cs
Normal file
67
support/tripviewer/web/Controllers/TripController.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Stores;
|
||||
using TripViewer.Utility;
|
||||
|
||||
|
||||
namespace TripViewer.Controllers
|
||||
{
|
||||
public class TripController : Controller
|
||||
{
|
||||
private readonly IConfiguration Configuration;
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
public TripController(IHttpClientFactory clientFactory, IConfiguration configuration)
|
||||
{
|
||||
_clientFactory = clientFactory;
|
||||
Configuration = configuration;
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var teamendpoint = Configuration.GetValue<string>("TRIPS_ROOT_URL");
|
||||
var bingMapsKey = Configuration.GetValue<string>("BING_MAPS_KEY");
|
||||
|
||||
//Get trips
|
||||
TripStore t = new TripStore(_clientFactory, teamendpoint);
|
||||
List<Trip> trips = t.GetItemsAsync().Result;
|
||||
//Get Last Trip
|
||||
var last = trips.Max(trip => trip.RecordedTimeStamp);
|
||||
var tlast = from Trip latest in trips
|
||||
where latest.RecordedTimeStamp == last
|
||||
select latest;
|
||||
//Get TripPoints
|
||||
TripPointStore tps = new TripPointStore(_clientFactory,teamendpoint);
|
||||
List<TripPoint> tripPoints = tps.GetItemsAsync(tlast.First()).Result;
|
||||
|
||||
ViewData["MapKey"] = bingMapsKey;
|
||||
return View(tripPoints);
|
||||
}
|
||||
|
||||
public PartialViewResult RenderMap()
|
||||
{
|
||||
var teamendpoint = Configuration.GetValue<string>("TRIPS_ROOT_URL");
|
||||
//Get trips
|
||||
TripStore t = new TripStore(_clientFactory, teamendpoint);
|
||||
List<Trip> trips = t.GetItemsAsync().Result;
|
||||
//Get Last Trip
|
||||
var last = trips.Max(trip => trip.RecordedTimeStamp);
|
||||
var tlast = from Trip latest in trips
|
||||
where latest.RecordedTimeStamp == last
|
||||
select latest;
|
||||
//Get TripPoints
|
||||
TripPointStore tps = new TripPointStore(_clientFactory, teamendpoint);
|
||||
List<TripPoint> tripPoints = tps.GetItemsAsync(tlast.First()).Result;
|
||||
|
||||
|
||||
return PartialView(tripPoints);
|
||||
}
|
||||
}
|
||||
}
|
117
support/tripviewer/web/Controllers/UserProfileController.cs
Normal file
117
support/tripviewer/web/Controllers/UserProfileController.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Simulator.DataObjects;
|
||||
using Simulator.DataStore.Stores;
|
||||
using TripViewer.Utility;
|
||||
|
||||
namespace TripViewer.Controllers
|
||||
{
|
||||
public class UserProfileController : Controller
|
||||
{
|
||||
private readonly IConfiguration Configuration;
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
|
||||
public UserProfileController(IConfiguration configuration, IHttpClientFactory clientFactory)
|
||||
{
|
||||
Configuration = configuration;
|
||||
_clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
// GET: UserProfile
|
||||
public ActionResult Index()
|
||||
{
|
||||
//"http://akstraefikopenhackefh3.eastus.cloudapp.azure.com";
|
||||
var teamendpoint = Configuration.GetValue<string>("USER_ROOT_URL");
|
||||
UserStore up = new UserStore(_clientFactory, teamendpoint, Configuration);
|
||||
List<User> userColl = up.GetItemsAsync().Result;
|
||||
var user = userColl[0];
|
||||
user.ProfilePictureUri = $"https://cdn4.iconfinder.com/data/icons/danger-soft/512/people_user_business_web_man_person_social-512.png";
|
||||
|
||||
if (user.TotalTrips > 0 && user.HardStops > 0)
|
||||
{
|
||||
var score = ((Convert.ToDouble(user.HardStops) / Convert.ToDouble(user.TotalTrips)) * 100);
|
||||
if (score < 100) { user.Rating = 80; } else { user.Rating = 50; }
|
||||
}
|
||||
|
||||
return View(userColl);
|
||||
}
|
||||
|
||||
// GET: UserProfile/Details/5
|
||||
public ActionResult Details(int id)
|
||||
{
|
||||
return View(id);
|
||||
}
|
||||
|
||||
// GET: UserProfile/Create
|
||||
public ActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: UserProfile/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public ActionResult Create(IFormCollection collection)
|
||||
{
|
||||
try
|
||||
{
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
// GET: UserProfile/Edit/5
|
||||
public ActionResult Edit(int id)
|
||||
{
|
||||
return View(id);
|
||||
}
|
||||
|
||||
// POST: UserProfile/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public ActionResult Edit(int id, IFormCollection collection)
|
||||
{
|
||||
try
|
||||
{
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
// GET: UserProfile/Delete/5
|
||||
public ActionResult Delete(int id)
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: UserProfile/Delete/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public ActionResult Delete(int id, IFormCollection collection)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Add delete logic here
|
||||
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
support/tripviewer/web/Models/DataObjects/BaseDataObject.cs
Normal file
18
support/tripviewer/web/Models/DataObjects/BaseDataObject.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
public interface IBaseDataObject
|
||||
{
|
||||
string Id { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class BaseDataObject : IBaseDataObject
|
||||
{
|
||||
public BaseDataObject() { Id = Guid.NewGuid().ToString(); }
|
||||
|
||||
public string Id { get ; set ; }
|
||||
}
|
||||
}
|
39
support/tripviewer/web/Models/DataObjects/Poi.cs
Normal file
39
support/tripviewer/web/Models/DataObjects/Poi.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class Poi
|
||||
{
|
||||
[JsonProperty("tripId")]
|
||||
public Guid TripId { get; set; }
|
||||
|
||||
[JsonProperty("latitude")]
|
||||
public double Latitude { get; set; }
|
||||
|
||||
[JsonProperty("longitude")]
|
||||
public double Longitude { get; set; }
|
||||
|
||||
[JsonProperty("poiType")]
|
||||
public long PoiType { get; set; }
|
||||
|
||||
[JsonProperty("timestamp")]
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
[JsonProperty("deleted")]
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
[JsonProperty("id")]
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public partial class Poi
|
||||
{
|
||||
public static Poi FromJson(string json) => JsonConvert.DeserializeObject<Poi>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class PoiSerializer
|
||||
{
|
||||
public static string ToJson(this Poi self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
}
|
63
support/tripviewer/web/Models/DataObjects/Trip.cs
Normal file
63
support/tripviewer/web/Models/DataObjects/Trip.cs
Normal file
@ -0,0 +1,63 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class Trip
|
||||
{
|
||||
[JsonProperty("Id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("UserId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("RecordedTimeStamp")]
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("EndTimeStamp")]
|
||||
public DateTime EndTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("Rating")]
|
||||
public long Rating { get; set; }
|
||||
|
||||
[JsonProperty("IsComplete")]
|
||||
public bool IsComplete { get; set; }
|
||||
|
||||
[JsonProperty("HasSimulatedOBDData")]
|
||||
public bool HasSimulatedObdData { get; set; }
|
||||
|
||||
[JsonProperty("AverageSpeed")]
|
||||
public long AverageSpeed { get; set; }
|
||||
|
||||
[JsonProperty("FuelUsed")]
|
||||
public long FuelUsed { get; set; }
|
||||
|
||||
[JsonProperty("HardStops")]
|
||||
public long HardStops { get; set; }
|
||||
|
||||
[JsonProperty("HardAccelerations")]
|
||||
public long HardAccelerations { get; set; }
|
||||
|
||||
[JsonProperty("Distance")]
|
||||
public double Distance { get; set; }
|
||||
|
||||
[JsonProperty("Created")]
|
||||
public DateTime Created { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public partial class Trip
|
||||
{
|
||||
public static Trip FromJson(string json) => JsonConvert.DeserializeObject<Trip>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class TripSerializer
|
||||
{
|
||||
public static string ToJson(this Trip self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
}
|
95
support/tripviewer/web/Models/DataObjects/TripPoint.cs
Normal file
95
support/tripviewer/web/Models/DataObjects/TripPoint.cs
Normal file
@ -0,0 +1,95 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
|
||||
public partial class TripPoint
|
||||
{
|
||||
[JsonProperty("Id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("TripId")]
|
||||
public Guid TripId { get; set; }
|
||||
|
||||
[JsonProperty("Latitude")]
|
||||
public double Latitude { get; set; }
|
||||
|
||||
[JsonProperty("Longitude")]
|
||||
public double Longitude { get; set; }
|
||||
|
||||
[JsonProperty("Speed")]
|
||||
public double Speed { get; set; }
|
||||
|
||||
[JsonProperty("RecordedTimeStamp")]
|
||||
public DateTime RecordedTimeStamp { get; set; }
|
||||
|
||||
[JsonProperty("Sequence")]
|
||||
public int Sequence { get; set; }
|
||||
|
||||
[JsonProperty("RPM")]
|
||||
public double Rpm { get; set; }
|
||||
|
||||
[JsonProperty("ShortTermFuelBank")]
|
||||
public double ShortTermFuelBank { get; set; }
|
||||
|
||||
[JsonProperty("LongTermFuelBank")]
|
||||
public double LongTermFuelBank { get; set; }
|
||||
|
||||
[JsonProperty("ThrottlePosition")]
|
||||
public double ThrottlePosition { get; set; }
|
||||
|
||||
[JsonProperty("RelativeThrottlePosition")]
|
||||
public double RelativeThrottlePosition { get; set; }
|
||||
|
||||
[JsonProperty("Runtime")]
|
||||
public double Runtime { get; set; }
|
||||
|
||||
[JsonProperty("DistanceWithMalfunctionLight")]
|
||||
public double DistanceWithMalfunctionLight { get; set; }
|
||||
|
||||
[JsonProperty("EngineLoad")]
|
||||
public double EngineLoad { get; set; }
|
||||
|
||||
[JsonProperty("EngineFuelRate")]
|
||||
public double EngineFuelRate { get; set; }
|
||||
|
||||
[JsonProperty("VIN")]
|
||||
public Vin Vin { get; set; }
|
||||
|
||||
[JsonProperty("CreatedAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("UpdatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public partial class Vin
|
||||
{
|
||||
[JsonProperty("String")]
|
||||
public string String { get; set; }
|
||||
|
||||
[JsonProperty("Valid")]
|
||||
public bool Valid { get; set; }
|
||||
}
|
||||
|
||||
public partial class TripPoint
|
||||
{
|
||||
public static TripPoint FromJson(string json) => JsonConvert.DeserializeObject<TripPoint>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class TripPointSerializer
|
||||
{
|
||||
public static string ToJson(this TripPoint self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
|
||||
internal static class Converter
|
||||
{
|
||||
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||
{
|
||||
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||
//DateParseHandling = DateParseHandling.None,
|
||||
//Converters = {new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.None } },
|
||||
};
|
||||
}
|
||||
}
|
104
support/tripviewer/web/Models/DataObjects/User.cs
Normal file
104
support/tripviewer/web/Models/DataObjects/User.cs
Normal file
@ -0,0 +1,104 @@
|
||||
namespace Simulator.DataObjects
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
public partial class User
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[JsonProperty("firstName")]
|
||||
public string FirstName { get; set; }
|
||||
|
||||
[JsonProperty("lastName")]
|
||||
[JsonConverter(typeof(ParseStringConverter))]
|
||||
public long LastName { get; set; }
|
||||
|
||||
[JsonProperty("userId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("profilePictureUri")]
|
||||
public string ProfilePictureUri { get; set; }
|
||||
|
||||
[JsonProperty("rating")]
|
||||
public long Rating { get; set; }
|
||||
|
||||
[JsonProperty("ranking")]
|
||||
public long Ranking { get; set; }
|
||||
|
||||
[JsonProperty("totalDistance")]
|
||||
public double TotalDistance { get; set; }
|
||||
|
||||
[JsonProperty("totalTrips")]
|
||||
public long TotalTrips { get; set; }
|
||||
|
||||
[JsonProperty("totalTime")]
|
||||
public long TotalTime { get; set; }
|
||||
|
||||
[JsonProperty("hardStops")]
|
||||
public long HardStops { get; set; }
|
||||
|
||||
[JsonProperty("hardAccelerations")]
|
||||
public long HardAccelerations { get; set; }
|
||||
|
||||
[JsonProperty("fuelConsumption")]
|
||||
public long FuelConsumption { get; set; }
|
||||
|
||||
[JsonProperty("maxSpeed")]
|
||||
public long MaxSpeed { get; set; }
|
||||
|
||||
[JsonProperty("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[JsonProperty("createdAt")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("updatedAt")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[JsonProperty("deleted")]
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
|
||||
public partial class User
|
||||
{
|
||||
public static User FromJson(string json) => JsonConvert.DeserializeObject<User>(json, Converter.Settings);
|
||||
}
|
||||
|
||||
public static class UserSerializer
|
||||
{
|
||||
public static string ToJson(this User self) => JsonConvert.SerializeObject(self, Converter.Settings);
|
||||
}
|
||||
|
||||
internal class ParseStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null) return null;
|
||||
var value = serializer.Deserialize<string>(reader);
|
||||
long l;
|
||||
if (Int64.TryParse(value, out l))
|
||||
{
|
||||
return l;
|
||||
}
|
||||
throw new Exception("Cannot unmarshal type long");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
|
||||
{
|
||||
if (untypedValue == null)
|
||||
{
|
||||
serializer.Serialize(writer, null);
|
||||
return;
|
||||
}
|
||||
var value = (long)untypedValue;
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
|
||||
}
|
||||
}
|
11
support/tripviewer/web/Models/ErrorViewModel.cs
Normal file
11
support/tripviewer/web/Models/ErrorViewModel.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace TripViewer.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
42
support/tripviewer/web/Models/Stores/BaseStore.cs
Normal file
42
support/tripviewer/web/Models/Stores/BaseStore.cs
Normal file
@ -0,0 +1,42 @@
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
public class BaseStore
|
||||
//<T> : IBaseStore<T> where T : class, IBaseDataObject, new()
|
||||
{
|
||||
public string EndPoint { get; set; }
|
||||
public HttpClient Client { get; set; }
|
||||
public DateTime DateTime { get; set; }
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
|
||||
public BaseStore(IHttpClientFactory clientFactory)
|
||||
{
|
||||
_clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
public Task InitializeStore(string EndPoint)
|
||||
{
|
||||
Client = _clientFactory.CreateClient();
|
||||
Client.BaseAddress = new Uri(EndPoint);
|
||||
Client.DefaultRequestHeaders.Accept.Clear();
|
||||
|
||||
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
DateTime = DateTime.UtcNow;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
22
support/tripviewer/web/Models/Stores/IBaseStore.cs
Normal file
22
support/tripviewer/web/Models/Stores/IBaseStore.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Simulator.DataStore.Stores
|
||||
{
|
||||
public interface IBaseStore<T>
|
||||
{
|
||||
Task InitializeStoreAsync();
|
||||
|
||||
Task<T> GetItemAsync(string id);
|
||||
|
||||
Task<IEnumerable<T>> GetItemsAsync();
|
||||
|
||||
Task<bool> CreateItemAsync(T item);
|
||||
|
||||
Task<bool> UpdateItemAsync(T item);
|
||||
|
||||
Task<bool> DeleteItemAsync(T item);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user